__new__ and __init__ - why does this work?

Ethan Furman ethan at stoneleaf.us
Wed Aug 9 20:46:39 EDT 2017


On 08/09/2017 03:39 PM, Ian Kelly wrote:
> On Wed, Aug 9, 2017 at 2:20 PM, Ethan Furman wrote:
>> On 08/09/2017 12:59 PM, Ian Pilcher wrote:

>>> I do want to prevent frozenset.__init__ from being called *again* when
>>> an existing instance is returned, so I've decided to take this
>>> approach:
>>>
>>>       def __new__(cls, *args, **kwargs):
>>>           self = super(UniqueSet, cls).__new__(cls, *args, **kwargs)
>>>           self._initialized = False
>>>           return UniqueSet._registry.setdefault(self, self)
>>>
>>>       def __init__(self, *args, **kwargs):
>>>           if not self._initialized:
>>>               super(UniqueSet, self).__init__(self, *args, **kwargs)
>>>               self._initialized = True
>>
>>
>> Whom do you think is going to call __init__ a second time?
>
> The __call__ method of the metaclass. Here's an example using a singleton class:
>
>--> Singleton()
> __init__ called 1 times
> <__main__.Singleton object at 0x76b54a717518>
>--> Singleton()
> __init__ called 2 times
> <__main__.Singleton object at 0x76b54a717518>
>--> Singleton() is Singleton()
> __init__ called 3 times
> __init__ called 4 times
> True

Ah, cool!  I hadn't known about that particular side effect of singletons.

--
~Ethan~




More information about the Python-list mailing list