Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does __call__ actually work?

Tags:

Python's magic method __call__ is called whenever you attempt to call an object. Cls()() is thus equal to Cls.__call__(Cls()).

Functions are first class objects in Python, meaning they're just callable objects (using __call__). However, __call__ itself is a function, thus it too has __call__, which again has its own __call__, which again has its own __call__.

So Cls.__call__(Cls()) is thus equal to Cls.__call__.__call__(Cls()) and again equilevant to Cls.__call__.__call__.__call__(Cls()) and so on and so forth.

How does this infinite loop end? How does __call__ actually execute the code?

like image 479
Markus Meskanen Avatar asked Sep 30 '15 00:09

Markus Meskanen


People also ask

How does __ add __ work?

__add__ magic method is used to add the attributes of the class instance. For example, let's say object1 is an instance of a class A and object2 is an instance of class B and both of these classes have an attribute called 'a', that holds an integer.

How do you call the __ str __ method?

Python __str__() This method returns the string representation of the object. This method is called when print() or str() function is invoked on an object. This method must return the String object.

What does the __ New__ method do?

The __new__() is a static method of the object class. When you create a new object by calling the class, Python calls the __new__() method to create the object first and then calls the __init__() method to initialize the object's attributes.

What are __ methods in Python?

The __call__ method enables Python programmers to write classes where the instances behave like functions. Both functions and the instances of such classes are called callables.


1 Answers

Under the hood, all calls in Python use the same mechanism, and almost all arrive at the same C function in the CPython implementation. Whether an object is an instance of a class with a __call__ method, a function (itself an object), or a builtin object, all calls (except for optimized special cases) arrive at the function PyObject_Call. That C function gets the object's type from the ob_type field of the object's PyObject struct, and then from the type (another PyObject struct) gets the tp_call field, which is a function pointer. If tp_call is not NULL, it calls through that, with the args and kwargs structures that were also passed to PyObject_Call.

When a class defines a __call__ method, that sets up the tp_call field appropriately.

Here's an article explaining all of this in detail: Python internals: How callables work. It even lists and explains the entire PyObject_Call function, which isn't very big. If you want to see that function in its native habitat, it's in Objects/abstract.c in the CPython repo.

Also relevant is this stackoverflow Q&A: What is a "callable" in Python?.

like image 149
BrianO Avatar answered Nov 22 '22 07:11

BrianO