I\'m currently trying my hands on the new dataclass constructions introduced in Python 3.7. I am currently stuck on trying to do some inheritance of a parent class. It looks
You're seeing this error because an argument without a default value is being added after an argument with a default value. The insertion order of inherited fields into the dataclass is the reverse of Method Resolution Order, which means that the Parent
fields come first, even if they are over written later by their children.
An example from PEP-557 - Data Classes:
@dataclass class Base: x: Any = 15.0 y: int = 0 @dataclass class C(Base): z: int = 10 x: int = 15
The final list of fields is, in order,
x, y, z
. The final type ofx
isint
, as specified in classC
.
Unfortunately, I don't think there's any way around this. My understanding is that if the parent class has a default argument, then no child class can have non-default arguments.
The approach below deals with this problem while using pure python dataclasses
and without much boilerplate code.
The ugly_init: dataclasses.InitVar[bool]
serves as a pseudo-field just to help us do initialization and will be lost once the instance is created. While ugly: bool = field(init=False)
is an instance member which will not be initialized by __init__
method but can be alternatively initialized using __post_init__
method (you can find more here.).
from dataclasses import dataclass, field
@dataclass
class Parent:
name: str
age: int
ugly: bool = field(init=False)
ugly_init: dataclasses.InitVar[bool]
def __post_init__(self, ugly_init: bool):
self.ugly = ugly_init
def print_name(self):
print(self.name)
def print_age(self):
print(self.age)
def print_id(self):
print(f'The Name is {self.name} and {self.name} is {self.age} year old')
@dataclass
class Child(Parent):
school: str
jack = Parent('jack snr', 32, ugly_init=True)
jack_son = Child('jack jnr', 12, school='havard', ugly_init=True)
jack.print_id()
jack_son.print_id()