python - 为什么数据类不能在其类属性声明中具有可变默认值?

标签 python python-3.x

似乎之前很可能被问过,但是一个小时左右的搜索没有产生任何结果。 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 variable x, 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 class D that do not specify a value for x when creating a class instance will share the same copy of x. 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 a ValueError if it detects a default parameter of type list, dict, or set. This is a partial solution, but it does protect against many common errors.

关于python - 为什么数据类不能在其类属性声明中具有可变默认值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53632152/

相关文章:

python - PyCharm 能否自动生成 __eq__() 和 __hash__() 实现?

python - 在沙盒 Pypy 中使用套接字模块

python - 如何用度数而不是弧度来计算切线?

python - Z3 字符串/字符异或?

python-3.x - 暂停执行直到按下按钮

python - aws cli : ERROR:root:code for hash md5 was not found

python - 使用python将Linux文件中的信息解析到Windows

类实例与局部(numpy)变量的 Python 性能

mysql - 如何使用 python 从 .sql (mysqldump) 文件执行 "Create table query"

python-3.x - 不使用 asyncio 编写 EventLoop