原文:https://zhuanlan.zhihu.com/p/59658886
作者:没有50CM手臂
网站:知乎
场景还原
最近开发遇到一个问题是在python3.7
的dataclass
中不能使用可变的默认值,错误如下:
@dataclass class Foo: bar: list = [] # ValueError: mutable default <class 'list'> for field a is not allowed: use default_factory
收到这种错误之后,修改为如下即可:
from dataclasses import ( dataclass, field ) @dataclass class Foo: bar: list = field(default_factory=list)
深层解读
看起来我的问题在文档中得到了很清楚的回答(来自PEP 557,正如shmee所提到的):
Python在类属性中存储默认成员变量值。考虑这个例子,不使用数据类:
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
请注意,类的两个实例按预期C共享相同的类变量x。
使用数据类,如果此代码有效:
@dataclass class D: x: List = [] def add(self, element): self.x += element
它会生成类似于的代码:
class D: x = [] def __init__(self, x=x): self.x = x def add(self, element): self.x += element'
这与使用类的原始示例具有相同的问题C。也就是说,在创建类实例时D没有指定值x的两个类实例将共享相同的副本x。由于数据类只使用普通的Python类创建,因此它们也会共享此行为。数据类没有通用的方法来检测这种情况。相反,数据类将抛出一个TypeError,如果它检测类型的默认参数list,dict或set。这是一个部分解决方案,但它可以防止许多常见错误。
标签:dataclasses,python,self,list,element,add,dataclass,默认值,class From: https://www.cnblogs.com/ajianbeyourself/p/17336447.html