Passing default list argument to dataclasses

PythonPython 3.xPython Dataclasses

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionH.BukhariView Question on Stackoverflow
Solution 1 - PythonAran-FeyView Answer on Stackoverflow
Solution 2 - PythongessulatView Answer on Stackoverflow