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__
参数
我为我的实体使用 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__
参数