I'd like to use @dataclass to remove a lot of boiler plate, but I also like the data encapsulation offered by @property. Can I do both simultaneously?
As a toy example, I have a class like
class Breakfast:
def __init__(self, sausage: str, eggs: str = "Scrambled", coffee: bool = False):
self._sausage = sausage
self._eggs = eggs
self._coffee = coffee
@property
def sausage(self):
return self._sausage
@property
def eggs(self):
return self._eggs
@property
def coffee(self):
return self._coffee
def __repr__(self):
...
def __eq__(self):
...
where I may also have setters for some of properties. What I'd like, is to write this in some form like this
@dataclass(property=True)
class DataBreakfast:
sausage: str
eggs: str = "Scrambled"
coffee: bool = False
(where, of course, my decorator argument doesn't work) that would do all the routine stuff that @dataclass does, and essentially outputs the code of the first snippet. I could then manually add setters in the rest of the class body at my leisure.
This seems like a common enough use case, but I couldn't figure out a way of getting it to work. The frozen parameter is the closest to what I want, but it doesn't really behave like @property as it precludes any kind of setter.
frozen
, or, of you only want it on some fields,semi
. If you want to skip writing the@property
, and only want to add a getter sometimes, you're out of luck because you're going to get a type-error while the class-body is parsed, even before the dataclass-decorator gets to apply its logic. And if you want to add logic like an access-counter, you'll have to write the property anyway.__repr__
for free.@foo.setter
means (won't be able to offer any completion hints). Of course its simple enough to define your own metaclass that automatically converts every dataclass field to a property, and would likely be the approach that I suggest for now (unlessdataclasses
adds this kind of support somewhere down the road)