我想在我的课程中传递默认参数, 但不知何故我遇到了问题:
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
我在做什么错了?
答案 0 :(得分:10)
field()
的参数为:
- default_factory::如果提供,则必须为零参数可调用, 需要此字段的默认值时将调用。其中 其他目的,可以用来指定可变的字段 默认值,如下所述。两者都指定是错误的 默认和default_factory。
您的default_factory
不是可调用的0参数,而是一个列表,这是导致错误的原因:
@dataclass
class Pizza():
ingredients: List = field(default_factory=['dow', 'tomatoes']) # <- wrong!
改为使用lambda函数:
@dataclass
class Pizza():
ingredients: List = field(default_factory=lambda: ['dow', 'tomatoes'])
答案 1 :(得分:2)
对于复杂的数据类型,我倾向于这样缩写:
from dataclasses import dataclass, field
from typing import Dict, Tuple
def default_field(obj):
return field(default_factory=lambda: obj)
@dataclass
class C:
complex_attribute: Dict[str, Tuple[int, str]] = default_field({"a": (1, "x"), "b": (1, "y")})
答案 2 :(得分:-1)
这种方法不使用typing
或dataclasses
模块,但是您可能想尝试以下方法:
class Pizza():
defaults = {
'toppings': ['peppers', 'cheese'],
'ingredients': ['dough', 'tomato'],
'meat': 'chicken'
}
def __init__(self, toppings=None, meat=None, ingredients=None):
if toppings is None:
setattr(self, 'toppings', defaults['toppings'])
if meat is None:
setattr(self, 'meat', defaults['meat'])
if ingredients is None:
setattr(self, 'ingredients', defaults['ingredients'])
我本可以将__init__
中的参数设置为其默认值,但是我认为此可能在引用同一列表时会引起冲突。