Search code examples
pythoninheritancepython-dataclasses

Python dataclass inheritance with default values


I am attempting to subclass a Python dataclass, where the subclass will have all the same fields as the parent class, except certain fields will be constrained to specific values.

That is, I am attempting to do something like this:

@dataclass
class Polygon:
    perimeter: float
    number_of_sides: int

class Triangle(Polygon):
    perimeter: float
    number_of_sides: int = 3

This works until I attempt to actually use the Triangle class without specifying number_of_sides.

This works as expected:

polygon = Polygon(perimeter=5.0, number_of_sides=6)
triangle = Triangle(perimeter=5.0, number_of_sides=3)

This does not work:

triangle_using_defaults = Triangle(perimeter=5.0)

Error message is

Traceback (most recent call last):
  File "/home/dmayo/PycharmProjects/playground/interval/shape.py", line 17, in <module>
    triangle_using_defaults = Triangle(perimeter=5.0)
                              ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Polygon.__init__() missing 1 required positional argument: 'number_of_sides'

How can I achieve this?


Solution

  • You're missing the @dataclass decorator for Triangle class;

    from dataclasses import dataclass
    
    @dataclass
    class Polygon:
        perimeter: float
        number_of_sides: int
    
    @dataclass
    class Triangle(Polygon):
        number_of_sides: int = 3
    
    triangle_using_defaults = Triangle(perimeter=5.0)
    print(triangle_using_defaults)
    

    This will print Triangle(perimeter=5.0, number_of_sides=3)

    Note: there's no need to specify perimeter: float in the subclass, as it is already defined in its parent, unless there is a need to override the parent's definition (as we do with the default value for number_of_sides).