need to understand the flow of __init__, __new__ and __call__

前端 未结 1 1924
长发绾君心
长发绾君心 2020-12-24 15:58
class Singleton(type):
    def __init__(self, *args, **kwargs):
        print \'calling __init__ of Singleton class\', self
        print \'args: \', args
        pr         


        
相关标签:
1条回答
  • 2020-12-24 16:31

    Your code doesn't include any __new__, so little can be said about it.

    But you create a metaclass which is instantiated at the time class A is created. In other words, the class A is an object itself and as such an instance of its metaclass Singleton.

    So let's look what happens:

    After A's environment is finished (its methods exist, its dict exists as well, ...), the class gets created as an instance of the metaclass. Essentially, the call is

    A = Singleton('A', (object,), <the dict>)
    

    where <the dict> is the dict containing the class's namespace (here: __module__, __metaclass__ and __init__).

    On this call to Singleton, calling super(Singleton, self).__call__(*args, **kwargs) results in calling the __new__ method which returns a new instance, on which .__init__ is called afterwards.

    That's why this happens:

    calling __init__ of Singleton class <class '__main__.A'>
    args:  ('A', (<type 'object'>,), {'__module__': '__main__', '__metaclass__': <class '__main__.Singleton'>, '__init__': <function __init__ at 0x01F9F7B0>})
    kwargs:  {}
    

    After A is constructed, you use it by instantiating it:

    a = A(10)
    

    This calls A. A is an instance of Singleton, so Singleton.__call__ is invoked – with the effect you see:

    running __call__ of Singleton <class '__main__.A'>
    args:  (10,)
    kwargs:  {}
    

    Singleton.__call__ calls type.__call__, this calls A.__new__ and A.__init__:

    in __init__ of A:   <__main__.A object at 0x01FA7A10>
    self.a:  10
    

    Then you do

    b = A(20)
    

    which calls Singleton.__call__:

    running __call__ of Singleton <class '__main__.A'>
    args:  (20,)
    kwargs:  {}
    

    Here the super call is suppressed and the old object is returned.

    0 讨论(0)
提交回复
热议问题