Re: [Python-Dev] Dataclasses, frozen and __post_init__

2018年2月20日 08:48:20 -0800

On Mon, Feb 19, 2018 at 8:16 PM, Glenn Linderman <[email protected]>
wrote:
> On 2/19/2018 7:02 PM, Guido van Rossum wrote:
>
> But how?
>
> On Mon, Feb 19, 2018 at 5:06 PM, Chris Barker - NOAA Federal <
> [email protected]> wrote:
>
>> ... maybe it would be helpful to be able to
>> freeze an instance after creation for multiple use-cases?
>>
>
> And there's the crux of the issue... if the creator of Python can't figure
> out how to make mutable objects immutable by fiat after creation, then it
> is unlikely anyone else can!
>
Um, the question was meant in the Socratic way. :-)
(Snipped the rest.)
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__()
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.
(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.)
-- 
--Guido van Rossum (python.org/~guido)
_______________________________________________
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to