I would like to "mix and match" instance attributes and dataclass fields, effectively extending dataclasses to optional attributes with computable values. I try to do this by using a default dataclass (so no explicit init method), but instantiating instance attributes (not Fields) in __post_init__
. That does not seem to please my IDE, though, as it warns me that these attributes were "defined outside an init method".
import dataclasses from typing import Optional, List
@dataclasses.dataclass
class Word:
text: str
def __post_init__(self):
self.chars: List[str] = self.text.split()
self.alt_text: Optional[str] = None
self.alt_text_chars: Optional[List[str]] = None
def add_alt_text(self, text: str):
self.alt_text = text # IDE complains that instance attribute is defined outside init
self.alt_text_chars = text.split() # IDE complains
word = Word("hello")
word.add_alt_text("good morning")
Does that mean that what I want to achieve is not possible, i.e. mixing instance attributes alongside regular dataclass fields? Or is there a (PEP-y) way around that is allowed?
As a side note: sometimes you explicitly want attributes to not be treated the same as fields. For instance, when your dataclass has __eq__
(the default), then you may want to compare ONLY the fields but not all of its attributes.
You can manage fields by listing them in the dataclass using field()
and passing init=False
and compare=False
to the field
call, although I am not sure this is what you are looking for.