[Python-Dev] Dataclasses, frozen and __post_init__

Guido van Rossum guido at python.org
Sat Feb 17 14:35:48 EST 2018


Why can'y you make `name` on `NamedObjectItem` a property that returns `
self.obj.name`? Why store a duplicate copy of the name?

PS. I have to ponder why frozen dataclasses don't use `__new__`.

On Fri, Feb 16, 2018 at 11:43 PM, Ben Lewis <benlewisj at gmail.com> wrote:

> On Sat, Feb 17, 2018 at 6:40 PM, Guido van Rossum <guido at python.org>
> wrote:
>>
>>
>> That's a pretty tricky proposal, and one that's been debated on and off
>> for a long time in other contexts. And that flag would somehow have to be
>> part of every instance's state.
>>
>
>> In general the right way to initialize an immutable/frozen object is not
>> through __init__ but through __new__ -- have you tried that?
>>
>
> Constructing it throught __new__ doesn't actually work as it has no way to
> alter the arguments that are passed into __init__, I think creating a
> metaclass that overides __call__ is required to acheive the desired result.
> Although a factory classmethod would acheive similar api.
>
>
>>
>> Also, a small example that demonstrates your need would do wonders to
>> help us understand your use case better.
>>
>>
>
> # unrelated object
> class NamedObject:
>     @property
>     def name(self) -> str:
>         return "some name"
>
> // has may subclasses
> @dataclass
> class Item:
>     name: str
>
>
> @dataclass
> class NamedObjectItem(Item):
>     name: str = field(init=False)
>     obj: NamedObject
>
>     def __post_init__(self):
>         self.name = self.obj.name
>
> This works fine, until I decided them Item and therefore all subclasses
> should be frozen as no instances are mutated
> and if they are ever in the future then its a bug. But to do this the
> following factory method needs to be added:
>
> @classmethod
> def create(cls, obj: NamedObject, *args, **kwargs):
>     return cls(obj.name, obj, *args, **kwargs)
>
> This doesn't look that bad but all fields(up to the last field used that
> would have been used in __post_init__) needs to be declared in the
> signature.
>
> Thanks
> Ben Lewis
>



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


More information about the Python-Dev mailing list