属性的正确使用方法
Correct way to use properties
我的属性getter/setters之前
class Child(Base):
@property
def prop(self) -> Optional[int]:
"""Doc"""
return getattr(self, "_prop", None)
@prop.setter
def prop(self, value: int):
self._set("prop", value) # where _set itself is a method to reduce boilerplate
现在,
prop = Prop.int_prop("prop", "Doc")
其中 Prop.int_prop
看起来像这样:
@staticmethod
def int_prop(name: str, doc: str) -> property:
def fget(self: Base) -> Optional[int]:
return getattr(self, "_" + name, None)
def fset(self: Base, value: int) -> None:
self._set(name, value)
return property(fget, fset, doc=doc)
编辑:_set
方法
# Dump value to event store if event exists
event = self._events.get(name)
if event:
logger.info(f"Dumping value {value} to {repr(event)}")
event.dump(value)
# Assign value to local variable
setattr(self, "_" + name, value)
一方面,这让我感到自豪,因为我正在从事的项目中有近 70% 是 属性 getters/setters。虽然我同意上面的方法更 Pythonic 和干净,下面的方法减少了很多代码。但是,它剥夺了 VS Code 在 属性 名称下方显示文档字符串的能力。
是否有解决此问题的方法或总体上更好的方法?
除非 VS Code 支持 PEP-257 的属性文档字符串定义,否则这只能被视为扩展注释而不是正确答案。我从未使用过 VS Code,无法测试它对此的支持。
在防御中,它在语法上提供文档字符串,而不是在运行时动态设置 __doc__
属性,因此它有机会解决问题中提出的主要问题。
如果我不关心IDE支持,我会写一个自定义描述符并遵循属性文档字符串的PEP-257指南。
# Adapted from examples in https://docs.python.org/3/howto/descriptor.html
class IntPropety:
def __set_name__(self, owner, name):
self.public_name = name
self.private_name = "_" + name
def __get__(self, obj, objtype=None) -> Optional[int]:
if obj is None:
return self
return getattr(obj, self.private_name)
def __set__(self, obj, value):
event = obj._events.get(self.public_name)
if event:
logger.info(f"Dumping value {value} to {repr(event)}")
event.dump(value)
setattr(obj, self.private_name, value)
class Child(Base):
prop = IntProperty()
"""Doc"""
我的属性getter/setters之前
class Child(Base):
@property
def prop(self) -> Optional[int]:
"""Doc"""
return getattr(self, "_prop", None)
@prop.setter
def prop(self, value: int):
self._set("prop", value) # where _set itself is a method to reduce boilerplate
现在,
prop = Prop.int_prop("prop", "Doc")
其中 Prop.int_prop
看起来像这样:
@staticmethod
def int_prop(name: str, doc: str) -> property:
def fget(self: Base) -> Optional[int]:
return getattr(self, "_" + name, None)
def fset(self: Base, value: int) -> None:
self._set(name, value)
return property(fget, fset, doc=doc)
编辑:_set
方法
# Dump value to event store if event exists
event = self._events.get(name)
if event:
logger.info(f"Dumping value {value} to {repr(event)}")
event.dump(value)
# Assign value to local variable
setattr(self, "_" + name, value)
一方面,这让我感到自豪,因为我正在从事的项目中有近 70% 是 属性 getters/setters。虽然我同意上面的方法更 Pythonic 和干净,下面的方法减少了很多代码。但是,它剥夺了 VS Code 在 属性 名称下方显示文档字符串的能力。
是否有解决此问题的方法或总体上更好的方法?
除非 VS Code 支持 PEP-257 的属性文档字符串定义,否则这只能被视为扩展注释而不是正确答案。我从未使用过 VS Code,无法测试它对此的支持。
在防御中,它在语法上提供文档字符串,而不是在运行时动态设置 __doc__
属性,因此它有机会解决问题中提出的主要问题。
如果我不关心IDE支持,我会写一个自定义描述符并遵循属性文档字符串的PEP-257指南。
# Adapted from examples in https://docs.python.org/3/howto/descriptor.html
class IntPropety:
def __set_name__(self, owner, name):
self.public_name = name
self.private_name = "_" + name
def __get__(self, obj, objtype=None) -> Optional[int]:
if obj is None:
return self
return getattr(obj, self.private_name)
def __set__(self, obj, value):
event = obj._events.get(self.public_name)
if event:
logger.info(f"Dumping value {value} to {repr(event)}")
event.dump(value)
setattr(obj, self.private_name, value)
class Child(Base):
prop = IntProperty()
"""Doc"""