web-dev-qa-db-fra.com

Passer l'argument de liste par défaut aux classes de données

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?

7
H.Bukhari

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'])
16
Aran-Fey

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