Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dataclasses.asdict() not working as expected

I'm using dataclass and asdict from dataclasses, and I find that asdict doesn't work as I would expect when I introduce inheritance.

I use dataclasses to help me create dictionaries from classes so I can pass them into django.shortcuts.render.

from dataclasses import dataclass
from dataclasses import asdict

@dataclass
class Base:
    name: str

class Test(Base):
    def __init__(self, age, *args, **kwargs):
        self.age = age
        super(Test, self).__init__(*args, **kwargs)

test = Test(age=20, name="john doe")

print(asdict(test))

I would expect the output to be

{"age": 20, "name": "john doe"}

But what I get is only the keyword-value from the base-class

{"name": "john doe"}
like image 761
Kent Martin Avatar asked Mar 04 '23 20:03

Kent Martin


1 Answers

The correct implementation for inheritance of a dataclass is covered in the docs:

@dataclass
class Base:
    name: str

@dataclass
class Child(Base):
    age: int

Without this, the __dataclass_fields__ attribute in the child class, which asdict uses to determine what should be in the dictionary, doesn't know about all of the fields you care about; it only has the inherited version:

>>> Test.__dataclass_fields__
{'name': Field(...)}
>>> Test.__dataclass_fields__ is Base.__dataclass_fields__
True
>>> Child.__dataclass_fields__
{'name': Field(...), 'age': Field(...)}
>>> Child.__dataclass_fields__ is Base.__dataclass_fields__
False

Also note you can simplify the imports to:

from dataclasses import asdict, dataclass
like image 136
jonrsharpe Avatar answered Mar 11 '23 22:03

jonrsharpe