Chr*_*ein 10 python python-dataclasses
我经常看到这样的代码:
@dataclass
class ClassName:
list_name: list[int] = field(default_factory=list)
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么我需要输入field(default_factory=list). 还不够吗list_name: list[int]?
您能解释一下何时、为什么以及如何在数据类中使用 field() 吗?
jua*_*aga 15
正在做:
list_name: list[int]
Run Code Online (Sandbox Code Playgroud)
不等于:
list_name: list[int] = field(default_factory=list)
Run Code Online (Sandbox Code Playgroud)
后者使用 a default_factory,所以注意:
>>> from dataclasses import dataclass
>>> @dataclass
... class ClassName:
... list_name: list[int]
...
>>> ClassName()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'list_name'
Run Code Online (Sandbox Code Playgroud)
但如果你使用默认工厂:
>>> @dataclass
... class ClassName:
... list_name: list[int] = field(default_factory=list)
...
>>> ClassName()
ClassName(list_name=[])
Run Code Online (Sandbox Code Playgroud)
请注意,如果您这样做list_name: list[int] = [],那么它将为每个实例重复使用相同的list对象,几乎肯定不是您想要的。事实上,dataclass装饰器明确拒绝了这一点:
>>> @dataclass
... class ClassName:
... list_name: list[int] = []
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/Users/juanarrivillaga/opt/miniconda3/envs/py39/lib/python3.9/dataclasses.py", line 1021, in dataclass
return wrap(cls)
File "/Users/juanarrivillaga/opt/miniconda3/envs/py39/lib/python3.9/dataclasses.py", line 1013, in wrap
return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
File "/Users/juanarrivillaga/opt/miniconda3/envs/py39/lib/python3.9/dataclasses.py", line 863, in _process_class
cls_fields = [_get_field(cls, name, type)
File "/Users/juanarrivillaga/opt/miniconda3/envs/py39/lib/python3.9/dataclasses.py", line 863, in <listcomp>
cls_fields = [_get_field(cls, name, type)
File "/Users/juanarrivillaga/opt/miniconda3/envs/py39/lib/python3.9/dataclasses.py", line 747, in _get_field
raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'list'> for field list_name is not allowed: use default_factory
Run Code Online (Sandbox Code Playgroud)
一般来说,dataclasses.field当您需要修改各个字段时,您可以显式地使用 a 。