[Python-Dev] Dataclasses, frozen and __post_init__

Guido van Rossum guido at python.org
Sun Feb 18 21:30:16 EST 2018


The underlying issue here is that we don't want an extra state flag in the
object to indicate "this object is currently [im]mutable". Using __class__
assignment to signal this is clever way to add this state, though not
without risks.

On Sun, Feb 18, 2018 at 4:34 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:

> On 18 February 2018 at 14:10, Guido van Rossum <guido at python.org> wrote:
> > Agreed the __pre_init__ idea is no improvement. I think we're back where
> you
> > started -- just use `object.__setattr__` to set the attribute in
> > `__post_init__`. That's what the PEP says is used by the generated
> > `__init__`, so I think it is reasonable to copy that pattern. Presumably
> the
> > situation doesn't occur that frequently in real code (__post_init__ feels
> > like a last resort hack anyway).
>
> FWIW, if someone really wanted to create a 3rd party context manager
> to assist with this they can do:
>
>     @contextmanager
>     def mutable(obj):
>         cls = obj.__class__
>         obj.__class__ = object
>         try:
>             yield obj
>         finally:
>             obj.__class__ = cls
>
>     @dataclass(frozen=True)
>     class C:
>        i: int
>        j: int = None
>        database: InitVar[DatabaseType] = None
>
>        def __post_init__(self, database):
>            if self.j is None and database is not None:
>                with mutable(self):
>                    self.j = database.lookup('j')
>
> Using object.__setattr__ explicitly would be clearer, though.
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
>



-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180218/1ceeabbf/attachment.html>


More information about the Python-Dev mailing list