【问题标题】:Why can't I assign values to an attribute after creating an instance of class?为什么在创建类实例后不能为属性赋值?
【发布时间】:2021-02-23 22:46:27
【问题描述】:

我刚刚发现了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_setattrvalidator的方式不对?

当我尝试使用 int 设置属性时,即 foobar.defaults = 1,正确引发了 ValueError。

任何提示表示赞赏。问候,托马斯

【问题讨论】:

    标签: python python-3.x python-attrs


    【解决方案1】:

    根据the documentationon_setattr

    如果没有引发异常,则将该属性设置为可调用对象的返回值。

    您的validate_dict 返回无,所以这就是设置的值。如果要将值设置为传入的dict,则需要在validate_dict 中执行return value。 (推测 API 是这样设置的,以便这样的处理程序可以修改传入的值,而不是简单地接受或拒绝它。)

    【讨论】:

    • 我的错,我太笨了。我应该更仔细地阅读文档。 Thx 解决了它。不要问我为什么我错过了返回值。我想我不应该那么晚做这些事情。 :)
    • 是的,这正是原因。这样就可以通过on_setattr 运行转换器。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 2019-04-07
    • 2012-01-10
    • 1970-01-01
    相关资源
    最近更新 更多