-1

我之前的属性获取器/设置器

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% 是属性 getter/setter。虽然我同意上面的方法更加 Pythonic 和干净,但下面的方法减少了很多代码。但是,它剥夺了 VS Code 在属性名称下方显示文档字符串的能力。

有没有解决这个问题或一般更好的方法?

4

1 回答 1

1

除非 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"""
于 2021-10-16T19:54:39.640 回答