这似乎之前很可能被问过,但是一个小时左右的搜索没有产生任何结果。 Passing default list argument to dataclasses看起来很有希望,但这并不是我想要的。
问题是:当一个人试图将一个可变值赋给一个类属性时,出现了一个错误:
@dataclass
class Foo:
bar: list = []
# ValueError: mutable default <class 'list'> for field a is not allowed: use default_factory
我从错误消息中了解到我应该改用以下内容:
@dataclass
class Foo:
bar: list = field(default_factory=list)
但为什么不允许可变默认值?是否强制避免 mutable default argument problem ?
最佳答案
看来我的问题在the docs 中得到了相当明确的回答。 (源自 PEP 557 ,如 shmee 所述):
Python stores default member variable values in class attributes. Consider this example, not using dataclasses:
class C: x = [] def add(self, element): self.x.append(element) o1 = C() o2 = C() o1.add(1) o2.add(2) assert o1.x == [1, 2] assert o1.x is o2.x
Note that the two instances of class
C
share the same class variablex
, as expected.Using dataclasses, if this code was valid:
@dataclass class D: x: List = [] def add(self, element): self.x += element
it would generate code similar to:
class D: x = [] def __init__(self, x=x): self.x = x def add(self, element): self.x += element
This has the same issue as the original example using class
C
. That is, two instances of classD
that do not specify a value forx
when creating a class instance will share the same copy ofx
. Because dataclasses just use normal Python class creation they also share this behavior. There is no general way for Data Classes to detect this condition. Instead, dataclasses will raise aValueError
if it detects a default parameter of typelist
,dict
, orset
. This is a partial solution, but it does protect against many common errors.
关于python - 为什么数据类不能在其类属性声明中具有可变默认值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53632152/