为什么我不能在创建 class 的实例后为属性赋值?
Why can't I assign values to an attribute after creating an instance of class?
我刚刚发现 attrs
,它对我即将开展的项目非常有用。在四处玩耍时,我发现了一些我无法向自己解释的行为。
我有这段代码:
from attr import attrs, attrib, Factory
def validate_dict(instance, attribute, value):
if not isinstance(value, dict):
raise ValueError(f"Attribute `{attribute.name}` has to be of type dict(), not {type(value)}!")
@attrs(kw_only=True, on_setattr=validate_dict)
class FooBar:
defaults = attrib(default=Factory(dict), validator=validate_dict)
config = attrib(default=Factory(dict), validator=validate_dict)
source = attrib(default=Factory(dict), validator=validate_dict)
target = attrib(default=Factory(dict), validator=validate_dict)
>>> foobar = FooBar()
>>> foobar
FooBar(defaults={}, config={}, source={}, target={})
>>> foobar.defaults = {'firstname':'Thomas'}
>>> foobar
FooBar(defaults=None, config={}, source={}, target={})
使用 foobar.defaults.update(firstname='Thomas')
可以,foobar = FooBar(defaults={'firstname':'Thomas'})
也可以,但直接分配不应该也可以吗?还是我使用 on_setattr
和 validator
的方式不对?
当我尝试使用 int 设置属性时,即 foobar.defaults = 1
正确引发了 ValueError。
感谢任何提示。此致,托马斯
根据 the documentation on_setattr
:
If no exception is raised, the attribute is set to the return value of the callable.
您的 validate_dict
returns None,因此这就是设置的值。如果要将值设置为传入的dict,则需要在validate_dict
中执行return value
。 (大概 API 是这样设置的,以便这样的处理程序可以修改传入的值,而不是简单地接受或拒绝它。)
我刚刚发现 attrs
,它对我即将开展的项目非常有用。在四处玩耍时,我发现了一些我无法向自己解释的行为。
我有这段代码:
from attr import attrs, attrib, Factory
def validate_dict(instance, attribute, value):
if not isinstance(value, dict):
raise ValueError(f"Attribute `{attribute.name}` has to be of type dict(), not {type(value)}!")
@attrs(kw_only=True, on_setattr=validate_dict)
class FooBar:
defaults = attrib(default=Factory(dict), validator=validate_dict)
config = attrib(default=Factory(dict), validator=validate_dict)
source = attrib(default=Factory(dict), validator=validate_dict)
target = attrib(default=Factory(dict), validator=validate_dict)
>>> foobar = FooBar()
>>> foobar
FooBar(defaults={}, config={}, source={}, target={})
>>> foobar.defaults = {'firstname':'Thomas'}
>>> foobar
FooBar(defaults=None, config={}, source={}, target={})
使用 foobar.defaults.update(firstname='Thomas')
可以,foobar = FooBar(defaults={'firstname':'Thomas'})
也可以,但直接分配不应该也可以吗?还是我使用 on_setattr
和 validator
的方式不对?
当我尝试使用 int 设置属性时,即 foobar.defaults = 1
正确引发了 ValueError。
感谢任何提示。此致,托马斯
根据 the documentation on_setattr
:
If no exception is raised, the attribute is set to the return value of the callable.
您的 validate_dict
returns None,因此这就是设置的值。如果要将值设置为传入的dict,则需要在validate_dict
中执行return value
。 (大概 API 是这样设置的,以便这样的处理程序可以修改传入的值,而不是简单地接受或拒绝它。)