Pasando el argumento de lista por defecto a las clases de datos

Me gustaría pasar el argumento predeterminado en mi clase, pero de alguna manera tengo un problema:

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) 

si escribo

 Pizza.ingredients 

Me sale el siguiente error:

————————————————– ————————- AttributeError Traceback (última llamada más reciente) en () —-> 1 Pizza.ingredients

AttributeError: el objeto de tipo ‘Pizza’ no tiene atributo ‘ingredientes’

Editar: con la instancia de clase obtuve el siguiente error:

 my_order = Pizza() 

————————————————– ————————- TypeError Traceback (última llamada más reciente) en () —-> 1 my_order = Pizza ()

en init (auto, ingredientes, carne)

TypeError: el objeto ‘list’ no se puede llamar

edición 2:

Verificación rápida con rendimientos de dir siguiente:

 ['__annotations__', '__class__', '__dataclass_fields__', '__dataclass_params__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'meat'] 

hay meat pero no ingredients

De los documentos dataclasses.field :

Los parámetros para el field() son:

  • default_factory: Si se proporciona, debe ser un argumento de cero invocable que se llamará cuando se necesite un valor predeterminado para este campo. Entre otros propósitos, esto se puede usar para especificar campos con valores predeterminados mutables, como se explica a continuación. Es un error especificar tanto default como default_factory.

Su default_factory no es un argumento de 0 invocable sino una lista, que es la razón del error:

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

Utilice una función lambda en su lugar:

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

Para tipos de datos complejos tiendo a abreviarme así:

 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")}) 

Este enfoque no utiliza el módulo de typing o de dataclasses , pero es posible que desee probar algo como lo siguiente:

 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']) 

Podría haber establecido los argumentos en __init__ a sus valores predeterminados, pero creo que esto puede causar conflictos al hacer referencia a la misma lista.