I was wondering if it would be possible to allow subclassing a dataclass without automatically including its fields in Subclass.__init__
(in some sense, hiding the inherited fields).
When subclassing the dataclass AB
below to create CD
, the fields of AB
become fields of CD
, automatically included in __init__
, __repr__
, and other methods of CD
.
@dataclass
class AB:
a: str
b: str
@dataclass
class CD(AB):
c: str
d: str
# CD is instantiated as `CD(a, b, c, d)`.
In some of my use cases, the values of a
and b
are determined by the values of c
and d
in instances of CD
(in some sense, instances of CD
are “fully determined” by c
and d
). Typically, I set those values in __post_init__
. However, since a
and b
are automatically included in some methods, I hide them manually:
@dataclass
class AB:
a: str
b: str
def hidden_field(default=MISSING):
return field(default=default, init=False, repr=False, compare=False)
@dataclass
class CD(AB):
c: str
d: str
a = hidden_field("Hello World")
b = hidden_field()
def __post_init__(self):
self.b = c + d
# CD is instantiated as `CD(c, d)`,
# but behavior from `AB` using `a` and `b` is still available.
I was wondering if, in the dataclass
decorator for CD
, an argument could be used to achieve this behavior, something like the following. I imagine this feature would be useful when a class like CD
needs behavior from AB
, but fields like a
and b
have predetermined values or values determined by fields of CD
. One potential issue is that comparison (I believe) is broken between CD
and AB
instances.
@dataclass
class AB:
a: str
b: str
@dataclass(hide_inherited_fields=True)
class CD(AB):
c: str
d: str
def __post_init__(self):
self.a = "Hello World"
self.b = c + d
# CD is instantiated as `CD(c, d)`.
Perhaps a specific set of fields could be ignored by the decorator argument, and the library could even include a function like hidden_field
.