Je voudrais passer l'argument par défaut dans ma classe, mais j'ai un problème:
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 j'essaie maintenant d'instancier Pizza
, j'obtiens l'erreur suivante:
>>> 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
Qu'est-ce que je fais mal?
De les dataclasses.field
Documents :
Les paramètres de
field()
sont:
- default_factory: S'il est fourni, il doit s'agir d'un appel à zéro argument qui sera appelé lorsqu'une valeur par défaut est nécessaire pour ce champ. Entre autres, cela peut être utilisé pour spécifier des champs avec des valeurs par défaut modifiables, comme expliqué ci-dessous. C'est une erreur de spécifier à la fois default et default_factory.
Votre default_factory
N'est pas un appel à 0 argument mais une liste, ce qui est la raison de l'erreur:
@dataclass
class Pizza():
ingredients: List = field(default_factory=['dow', 'tomatoes']) # <- wrong!
Utilisez plutôt une fonction lambda:
@dataclass
class Pizza():
ingredients: List = field(default_factory=lambda: ['dow', 'tomatoes'])
Pour les types de données complexes, j'ai tendance à abréger comme suit:
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")})