I am practicing on using the super function and dataclass inheritance in general. I have enabled the kw_only attribute for cases when the parent class has default values. I completely understand that super doesn't need to be used in a dataclass if you're just passing variables and I can avoid using super here. My goal is to understand the super feature better through this example. I can't understand the error message I'm getting though.
@dataclass(kw_only=True)
class ZooAnimals():
food_daily_kg: int
price_food: float
area_required: float
name: str
c = ZooAnimals(food_daily_kg=565, price_food=40, area_required=10, name='Monkey'
)
print(c)
@dataclass(kw_only=True)
class Cats(ZooAnimals):
meowing: str
def __init__(self, food_daily_kg, price_food, area_required, meowing, name):
self.meowing = meowing
super().__init__(food_daily_kg, price_food, area_required, name)
z = Cats(food_daily_kg=465, price_food=30, area_required=10, meowing='Little Bit',
name='Leopard'
)
print(z)
Output:
ZooAnimals(food_daily_kg=565, price_food=40, area_required=10, name='Monkey')
TypeError: ZooAnimals.__init__() takes 1 positional argument but 5 were given
You shouldn't define an __init__
method in a data class if you don't have any custom initialization logics. And if you do have custom initialization logics, you should define them in a __post_init__
method instead.
Your code produces the error because the __init__
method of the subclass calls the __init__
method of the base class with positional arguments when the method is configured to accept keyword arguments only with your kw_only=True
option.
You can fix it by passing keyword arguments instead, or by simply removing the __init__
method from the subclass entirely since one would be generated for the data class with inheritance in mind already.
For example, this subclass definition would work just fine:
@dataclass(kw_only=True)
class Cats(ZooAnimals):
meowing: str
Demo here
Or if you would still like to define a custom __init__
method for some reason:
@dataclass(kw_only=True)
class Cats(ZooAnimals):
meowing: str
def __init__(self, food_daily_kg, price_food, area_required, meowing, name):
self.meowing = meowing
super().__init__(
food_daily_kg=food_daily_kg,
price_food=price_food,
area_required=area_required,
name=name)
Demo here