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

H.B*_*ari 9 python oop type-hinting python-3.x

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

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)
Run Code Online (Sandbox Code Playgroud)

如果我打字

>>> 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
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

-------------------------------------------------- ------------------------- AttributeError Traceback(最近一次调用last)in()----> 1 Pizza.ingredients

AttributeError:类型对象'Pizza'没有属性'ingredients'

编辑:对于类实例我收到以下错误:

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)
Run Code Online (Sandbox Code Playgroud)

-------------------------------------------------- ------------------------- TypeError Traceback(最近一次调用last)in()----> 1 my_order = Pizza()

init(自我,成分,肉)

TypeError:'list'对象不可调用

编辑2:

快速检查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
Run Code Online (Sandbox Code Playgroud)

Pizza但不Pizza

Ara*_*Fey 18

dataclasses.field文档:

参数field()是:

  • default_factory:如果提供,则必须是零参数可调用,当此字段需要默认值时,将调用该调用.除了其他目的之外,这可以用于指定具有可变默认值的字段,如下所述.指定default和default_factory都是错误的.

default_factory不是一个0参数可调用但是一个列表,这是错误的原因:

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

使用lambda函数代替:

@dataclass
class Pizza():
    ingredients: List = field(default_factory=lambda: ['dow', 'tomatoes'])
Run Code Online (Sandbox Code Playgroud)

  • 在这种特定情况下,“list”作为类型提示就足够了。无需导入。 (3认同)
  • 为了方便以后参考,需要导入List和field。`从输入导入列表` `从数据类导入字段` (2认同)

ges*_*lat 11

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

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")})
Run Code Online (Sandbox Code Playgroud)

  • 您还应该将其设置为“copy.copy(obj)”,否则它将是共享可变的,并且这不是一件容易调试的事情。 (6认同)
  • 如果字典的值是可变的,则可以使用“copy.deepcopy(obj)”。在这种情况下,不是因为它们是元组。 (2认同)