15
class Singleton(type):
    def __init__(self, *args, **kwargs):
        print 'calling __init__ of Singleton class', self
        print 'args: ', args
        print 'kwargs: ', kwargs
        super(Singleton, self).__init__(*args, **kwargs)
        self.__instance = None
    def __call__(self, *args, **kwargs):
        print 'running __call__ of Singleton', self
        print 'args: ', args
        print 'kwargs: ', kwargs, '\n\n'
        if self.__instance is None:
            self.__instance = super(Singleton, self).__call__(*args, **kwargs)
        return self.__instance

class A(object):
    __metaclass__ = Singleton
    def __init__(self,a):
        print 'in __init__ of A:  ', self
        self.a = a
        print 'self.a: ', self.a

a=A(10)
b=A(20)

I copied this code from Ben's answer to the question Python's use of __new__ and __init__? and modified it a little. But, I am not aware of the flow. Although I understand from a higher level what this code is intended to do. But, internally how it works, I am not quite sure of.

I get the following output when running this code:-

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


in __init__ of A:   <__main__.A object at 0x01FA7A10>
self.a:  10
running __call__ of Singleton <class '__main__.A'>
args:  (20,)
kwargs:  {}

I cant understand how the args and kwargs for __init__ and __call__ become different. While using metaclasses, this link (What is a metaclass in Python?) has explained how to use __new__ and a function as a metaclass. But, I do not understand how __call__ is being used.

Can somebody explain the flow? By this, I mean, the precedence in which __new__, __call__, __init__ are called and who calls them?

Community
  • 1
  • 1
GodMan
  • 2,561
  • 2
  • 24
  • 40
  • 1
    The question is, what do you *want* to do? – phant0m Oct 19 '12 at 10:01
  • I am a newbie to many python concepts. I am trying to implement a Singleton class as mentioned in Ben's answer in the link: http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init. Also, during that implementation, I want to learn the internal flow of my program that I have written. – GodMan Oct 19 '12 at 10:06
  • Have you read the [documentation](http://docs.python.org/reference/datamodel.html#customizing-class-creation)? I highly recommend you read that page in its entirety. – phant0m Oct 19 '12 at 10:09
  • Yeah, but, it does not explain as well as glglgl has explained in his answer below. – GodMan Oct 19 '12 at 10:15

1 Answers1

14

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.

glglgl
  • 89,107
  • 13
  • 149
  • 217
  • Correct me if I am wrong. In your explanataion: `'On this call to Singleton, its __new__ is called and afterwards the .__init__ of the result.'`, by the word `result` , are you referring to the return value (which will act as the class which will create the class object `A`) from the implicit `__new__` method for the Singleton class? – GodMan Oct 19 '12 at 11:03
  • And, my other question is: can you give an example where the `kwargs` in the `__init__` of the class `Singleton` holds anything else than `{}` ? – GodMan Oct 19 '12 at 11:28
  • @GodMan I have rephrased the sentence. Yes, `Singleton.__call__` calls `A.__new__`, which returns a new instance, and then the new instance's `__init__`. – glglgl Oct 19 '12 at 18:00
  • To your 2nd question: No, a superclass will always be called with positional arguments, so that `kwargs` always stays empty. You could even change `*args` to `name, bases, dict` as the number of arguments is fixed as well. – glglgl Oct 19 '12 at 18:01
  • 2 requests again: 1. For the line `Singleton.__call__ calls type.__call__, this calls A.__new__ and A.__init__`, can you provide the parameters to each of A.__new__ and A.__init__ 2. For the call: `b = A(20)`, you have written that `Here the super call is suppressed and the old object is returned.`. Is it because an existing instance of `A` is returned by the `Singleton.__call__` that the `A.__init__` not called here? – GodMan Oct 20 '12 at 14:07
  • @GodMan 1. This is trivial: The arguments to `A` are what you give it, in your case it is `a`. But in order to get a portable metaclass, you should keep `Singleton.__call__` as common as possible (`*args`, `**kargs`). 2. Of course. As you test your `self.__instance` and skip the call if it is not `None` any longer, it is, well, skipped. – glglgl Oct 20 '12 at 18:04
  • Thanks for the 2nd one again. But, for the first one, which seems trivial, my doubt is: In your explanation, I can understand that (*args, **kwargs) in Singleton.__call__ is calling the __call__ of `type` class, which internally calls A.__new__ (probably). As Singleton.__call__ will call A.__new__, it is possible for me to manually define A.__new__ ? if yes, then, with what parameters does A.__new__ gets called ? – GodMan Oct 20 '12 at 18:27
  • `A.__new__` nearly gets the same arguments as `A.__init__`. The only difference is that it gets the class `cls` of the object-to-be-created as its 1st argument, while `__init__` gets `self`, the already-constructed object. – glglgl Oct 20 '12 at 21:30
  • Thanks a lot. Accepting your answers :) – GodMan Oct 21 '12 at 09:14