56

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

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

我究竟做错了什么?

4

2 回答 2

101

文档_dataclasses.field

参数为field()

  • default_factory:如果提供,它必须是一个零参数的可调用对象,当该字段需要默认值时将调用它。除其他目的外,这可用于指定具有可变默认值的字段,如下所述。同时指定 default 和 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'])
于 2018-08-28T18:26:49.400 回答
12

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

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")})
于 2018-12-20T14:16:41.413 回答