On Mon, Feb 19, 2018 at 8:16 PM, Glenn Linderman <v+pyt...@g.nevcal.com>
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 <
> chris.bar...@noaa.gov> 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
Python-Dev@python.org
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