attrs 包是否有 "on_getattr" 等效功能?

Is there "on_getattr" equivalent functionality for attrs package?

我为我的实体使用 attrs 包,它在大多数情况下都非常有效。我遇到的一个问题是为属性定义 getter(通常在纯 python @属性 中转到)

for setter attrs 有一个方便的参数 on_setattr 其工作方式如下:

@attr.s(kw_only=True)
class Customer:
    name = attr.ib(type=str, on_setattr=[prevent_empty_string, other_validators_or_logics, ])

它使我们在任何情况下几乎都无需使用 @name.setter(至少根据我的经验)

但是,当我们在返回属性时有一些逻辑时,我们当然不能使用:

@property
def name(...

因为它将覆盖我们 attrs 名称的原始定义。所以我想知道在这种情况下 attrs 中是否有任何内置方法,或者如果没有,除了定义另一个具有不同名称的属性之外还有其他解决方案,即

@property
def get_name(self):
    return self.name # or whatever

更新

一个解决方案是 using/overriding __getattribute__ 的 attr 添加如下逻辑:

@attr.s(kw_only=True)
class Customer:
    name = attr.ib(type=str, on_setattr=[prevent_empty_string, other_validators_or_logics, ])

    def __getattribute__(self, name: str) -> Any:
        if name == "name":
            return self.__dict__["name"].upper()
        return super().__getattribute__(name)

但最终,它会被大量 if/switch 块污染,更重要的是会与内置 __repr__

混淆

没有……到目前为止,假设是对于您的用例,您将拥有一个私有属性并在其之上定义一个 属性。

如果你这样做:

@attr.define
class Customer:
    _name: str = attr.field(on_setattr=[…])

    @property
    def name(self) -> str:
        return self._name.upper()

    @name.setter
    def name(self, value: str) -> None:
        self._name = value

你应该用更少的魔法元编程获得所有的好处。

N.B。 _name will still be name.

__init__ 参数