Every time I write a `class` statement in Python now, I wonder about this: https://blog.glyph.im/2023/02/data-classification.html
@glyph one thing I've been dealing with and is not handled well by dataclasses: init signatures that don't cleanly match the fields.
You can hand-roll the whole init, but then you loose immutability by default. I had to add it back with custom code.
Having private fields exposed as properties, with the init setting the private fields, also gets messier.
I still try to use dataclasses because of the repr, sort, etc, but they do make those 2 usecases more complicated than the default.
@tonnydourado frozen defaults to False so I don't know what you mean by "immutability by default". If you hand-roll the whole init, the behavior is still the same.
@glyph I mean if you hand roll the init, you can't use frozen=True at all, because you have to mutate self in the init.
@tonnydourado oh, hmmmm. perhaps a design decision that needs revisiting, given that then init=False, frozen=True is sort of mutually incoherent unless you do gymnastics like this
from dataclasses import dataclass
@dataclass(frozen=True, init=False)
class froz:
a: int
b: str
def __init__(self):
super().__setattr__("a", 7)
super().__setattr__("b", "lol")
print(froz())
@glyph there's another thing that intersects with it: a hand-rolled init is never overwritten, even if you don't set init=False. In fact, even if you set init=True, the init already present in the class will not be overwritten.
@glyph which means you can't just crosscheck frozen and init, for instance, to raise an error.
@tonnydourado maybe there needs to be a different hook? __pre_frozen_init__ or something? this is an ugly edge case
@glyph I feel like this is why god created __new__, but for some reason we never use it?