On 18 February 2018 at 14:10, Guido van Rossum <gu...@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   |   ncogh...@gmail.com   |   Brisbane, Australia
_______________________________________________
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