Understanding Python Class Instantiation

Let’s say you have a class Foo:

What happens when you instantiate it (create an instance of that class)?


This is a companion discussion topic for the original entry at http://amir.rachum.com/blog/2016/10/03/understanding-python-class-instantiation/

new() can also be used to subclass immutable types

Foo(*args, **kwargs) is not equivalent to Foo.__call__(*args, **kwargs) if Foo defines a method __call__ :

>>> class Foo:
...   def __call__(self):
...     print('running __call__')
...
>>> Foo()
<__main__.Foo object at 0x000000000227ABE0>
>>> Foo.__call__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __call__() missing 1 required positional argument: 'self'

In this case, __call__ is used to call instances of the class :

>>> Foo()()
running __call__
>>>

I was curios, maybe its more like being equivalent to type(Foo).__call__(Foo, *args, **kwargs)?

Did some experiments:

>>> class Foo:
...     def __call__(self):
...         print('Foo.__call__')
... 
>>> def call():
...     print('call')
... 
>>> instance = Foo()
>>> instance()
Foo.__call__
>>> instance.__call__ = call
>>> instance()
Foo.__call__
>>> type(instance).__call__(instance)
Foo.__call__
>>> type(Foo).__call__(Foo)
<__main__.Foo object at 0x10356e5c0>
>>> Foo.__class__.__call__(Foo)
<__main__.Foo object at 0x10356e588>

It seems that it actually calls __call__ on the class of an object.

Thank you for brilliant explanation!

Tiny comment. I think you have little mistake there. In 3rd item of list after words “In conclusion:” You probably meant not "calls type.__new__(Foo, *args, **kwargs)", but "calls obj_type.__new__(Foo, *args, **kwargs)".