Passing default list argument to dataclasses
PythonPython 3.xPython DataclassesPython Problem Overview
I would like to pass default argument in my class, but somehow I am having problem:
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)
If I now try to instantiate Pizza
, I get the following error:
>>> 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
What am I doing wrong?
Python Solutions
Solution 1 - Python
From the dataclasses.field
docs:
> The parameters to field()
are:
>
> - default_factory: If provided, it must be a zero-argument callable that
> will be called when a default value is needed for this field. Among
> other purposes, this can be used to specify fields with mutable
> default values, as discussed below. It is an error to specify both
> default and default_factory.
Your default_factory
is not a 0-argument callable but a list, which is the reason for the error:
from dataclasses import dataclass, field
from typing import List
@dataclass
class Pizza():
ingredients: List = field(default_factory=['dow', 'tomatoes']) # <- wrong!
Use a lambda function instead:
@dataclass
class Pizza():
ingredients: List = field(default_factory=lambda: ['dow', 'tomatoes'])
Solution 2 - Python
For complex datatypes i tend to abbreviate like so:
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")})