[Python-Dev] Dataclasses, frozen and __post_init__

Chris Barker chris.barker at noaa.gov
Tue Feb 20 15:50:09 EST 2018


On Tue, Feb 20, 2018 at 8:45 AM, Guido van Rossum <guido at python.org> wrote:

> TBH, I don't hate Nick's solution that assigns to __class__ in
> __post_init__. You can probably come up with a class decorator that hides
> construction of the frozen subclass. I do think that it should be used very
> sparingly, as the existence of the subclass is hard to hide: instances of
> MyRecord will show as instances of _LockedMyRecord when printed or
> otherwise inspected, which could be confusing.
>
> There's another very simple low-tech solution:
>
> @dataclass
> class MyRecord:
>     a: int
>     # etc.
>     frozen: bool = False
>     def freeze(self):
>         self.frozen = True
>     def __setattr__(self, name, value):
>         if self.frozen: raise AttributeError
>         super().__setattr__(name, value)
>     def __hash__(self):
>         assert self.frozen
>         return super().__hash__()
>

This sure seems far more straightforward and les magic than __class__
swapping.


> It can easily be weaponized via an extra decorator, and it's simpler in
> that it doesn't use a magical second class. I'm just not keen on adding the
> extra attribute to all frozen instances created via
> @dataclass(frozen=True), because it's extra space overhead.
>

Is that one attribute that big a deal? I suppose that simple dataclasses
with only two or so attributes would see a significant change, but if
you're really worried about space, wouldn't you use a namedtuple or simply
a tuple anyway?

(In fact you can conclude that I'm not keen on exposing *any* of these
> "solutions" as a flag on the @dataclass() decorator. They all feel pretty
> fragile to me.)
>

so provide a:

@freezable_dataclass

Additional decorator that folks that want the ability to freeze and
unfreeze instances can use?

and if it overrides __set__attr, it could be used an virtually any class to
make a frozen version, yes?

I can't say I have enough need to bother writing that myself, but if others
do -- it seems like a good solution.

-CHB


-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker at noaa.gov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180220/d6ed8e50/attachment.html>


More information about the Python-Dev mailing list