在 dataclasses.field 中使用显式 __init__ 构造函数和 default_factory 参数时,数据类属性丢失

Dav*_*oty 5 python python-dataclasses

以下代码创建一个Obj带有 int 字段n(默认值为 0)的数据类。

from dataclasses import dataclass, field

@dataclass
class Obj:
    n: int = field(default_factory=int)
    
a = Obj()
print(a.n)
Run Code Online (Sandbox Code Playgroud)
a.n = 0
Run Code Online (Sandbox Code Playgroud)

现在,添加一个显式__init__构造函数:

a.n = 0
Run Code Online (Sandbox Code Playgroud)

它现在生成此错误,声称该Obj对象没有名为 的属性n

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Input In [6], in <module>
      8         pass
     10 a = Obj()
---> 11 print(f'a.n = {a.n}')

AttributeError: 'Obj' object has no attribute 'n'
Run Code Online (Sandbox Code Playgroud)

我想也许显式__init__会覆盖field()正在执行的任何操作,但是如果我们从参数更改default_factorydefault,它会再次起作用:

@dataclass
class Obj:
    n: int = field(default_factory=int)
        
    def __init__(self): # explicit constructor
        pass
Run Code Online (Sandbox Code Playgroud)
a.n = 3
Run Code Online (Sandbox Code Playgroud)

此行为出现在 Python 3.8 和 3.10 中。

che*_*ner 7

field并没有真正“做”任何事情;dataclass它只是提供装饰器用来定义__init__创建和初始化属性的信息n。当您定义自己 __init__方法时,您有责任确保该字段根据 提供的定义进行初始化field。(对于定义的其他方法也是如此dataclass。)