将默认列表参数传递给数据类

Passing default list argument to dataclasses

我想在 class 中传递默认参数, 但不知何故我遇到了问题:

from dataclasses import dataclass, field
from typing import List

@dataclass
class Pizza():
    ingredients: List = field(default_factory=['dow', 'tomatoes'])
    meat: str = field(default='chicken')

    def __repr__(self):
        return 'preparing_following_pizza {} {}'.format(self.ingredients, self.meat)

如果我现在尝试实例化 Pizza,我会收到以下错误:

>>> my_order = Pizza()
Traceback (most recent call last):
  File "pizza.py", line 13, in <module>
    Pizza()
  File "<string>", line 2, in __init__
TypeError: 'list' object is not callable

我做错了什么?

来自the dataclasses.field docs

The parameters to field() are:

  • default_factory: If provided, it must be a zero-argument callable that will be called when a default value is needed for this field. Among other purposes, this can be used to specify fields with mutable default values, as discussed below. It is an error to specify both default and default_factory.

您的 default_factory 不是一个 0 参数可调用对象而是一个列表,这就是错误原因:

from dataclasses import dataclass, field
from typing import List

@dataclass
class Pizza():
    ingredients: List = field(default_factory=['dow', 'tomatoes'])  # <- wrong!

改为使用 lambda 函数:

@dataclass
class Pizza():
    ingredients: List = field(default_factory=lambda: ['dow', 'tomatoes'])

对于复杂的数据类型,我倾向于这样缩写:

import copy
from dataclasses import dataclass, field
from typing import Dict, Tuple

def default_field(obj):
    return field(default_factory=lambda: copy.copy(obj))

@dataclass
class C:
    complex_attribute: Dict[str, Tuple[int, str]] = default_field({"a": (1, "x"), "b": (1, "y")})