Can I provide defaults for a subclass of a dataclass?

Viewed 1020

I want to create a class hierarchy, where all objects of class Base has a field field1, but different subclasses have different default values for field1. The classes are data holders, so dataclasses seems like the perfect library to use.

Consider the following python 3.7+ code.

from dataclasses import dataclass, field
from typing import Any, Iterable

@dataclass
class Base:
    field1: Iterable[Any]

@dataclass
class Sub(Base):
    field2: Any
    field1: Iterable[Any] = field(default_factory=list)

The code fails, giving me TypeError: non-default argument 'field2' follows default argument. This is a little surprising, since field2 follows the non-default field1 of the superclass, and the defalt argument field1 of the class Sub actually comes after field2.

According to the example in the docs on dataclass inheritence though, fields in subclasses overrides the fields in superclasses, but field order is preserved. So the error makes sense.

Is there any suitable workaround here, or must I implement everything by hand?

1 Answers

You can use the @property decorator:

from dataclasses import dataclass
from typing import Any, Iterable

@dataclass
class Base:
    @property
    def field1(self) -> Iterable[Any]:
        return

@dataclass
class Sub(Base):
    field2: Any

    @property
    def field1(self) -> Iterable[Any]:
        return []  # or whatever default you want to put here
Related