[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