__new__ and __init__ - why does this work?

Ian Kelly ian.g.kelly at gmail.com
Wed Aug 9 18:39:52 EDT 2017


On Wed, Aug 9, 2017 at 2:20 PM, Ethan Furman <ethan at stoneleaf.us> 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:

class Singleton:
  _instance = None

  def __new__(cls):
    if cls._instance is None:
      cls._instance = super(Singleton, cls).__new__(cls)
    return cls._instance

  def __init__(self):
    self.count = getattr(self, 'count', 0) + 1
    print('__init__ called %d times' % self.count)

>>> 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

By the way, "whom" is not the verb object in "Whom do you think is
going to call", so it should properly be "who do you think is going to
call". I point this out because although I don't really care when
people use "who" incorrectly, it looks pretty silly (and pretentious)
to use "whom" incorrectly.



More information about the Python-list mailing list