我将命名元组用于不可变数据结构,直到遇到数据类,我在我的用例中更喜欢它(与问题无关)。
现在我了解到它们不是一成不变的!至少严格来说不是。setattr(frozen_dc_obj, "prop", "value")
引发异常。好的。
但是为什么object.__setattr__(frozen_dc_obj,..)
工作?
与 namedtuple
相比,它引发异常!
from collections import namedtuple
from dataclasses import dataclass
NTTest = namedtuple("NTTest", "id")
nttest = NTTest(1)
setattr(nttest, "id", 2) # Exception
object.__setattr__(nttest, "id", 2) # Exception
@dataclass(frozen=True)
class DCTest:
id: int
dctest = DCTest(1)
setattr(dctest, "id", 2) # Exception
object.__setattr__(dctest, "id", 2) # WORKS
最佳答案
namedtuple定义 __slots__ = ()
因此您不能设置任何属性(它没有 __dict__
)。
Frozen dataclasses另一方面,在他们的 __setattr__
中执行手动检查方法并在它是一个卡住实例时引发异常。
比较以下内容:
>>> class Foo:
... __slots__ = ()
...
>>> f = Foo()
>>> f.__dict__ # doesn't exist, so object.__setattr__ won't work
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__dict__'
>>> @dataclass(frozen=True)
... class Bar:
... pass
...
>>> b = Bar()
>>> b.__dict__ # this exists, so object.__setattr__ works
{}
关于python卡住数据类不可变对象(immutable对象).__setattr__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63818045/