Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - What does it mean for a Class to be callable?

I am trying to understand what 'callables' are in Python and what it means for a class to be callable. I was playing with the following code:

class A(object):

    def __init__(self):
        pass

print("Is A callable? " + str(callable(A)))
a=A()
print("created a")
a()

This gives the following result:

Is A callable? True
created a
Traceback (most recent call last):    
File "test2.py", line 11, in <module>
a()
TypeError: 'A' object is not callable  

Furthermore,

print(type(A.__call__()))

Gives:

<class '__main__.A'>

Does this mean that class A has a __call__ method? and why is it of type class?

is A.__call__() being called each time I instantiate with A()?

like image 398
Kevin L. Avatar asked Jan 26 '18 13:01

Kevin L.


People also ask

What is callable class in Python?

callable() is a built-in method in Python that checks if a passed object appears to be callable. To do this, it checks if the argument is either of the following: The type that demonstrates callability, such as a function or a method. An instance of a class with a __call__ method.

What defines a callable?

Definition of callable : capable of being called specifically : subject to a demand for presentation for payment callable bond.

What does callable mean coding?

A callable object, in computer programming, is any object that can be called like a function.


Video Answer


2 Answers

So, start with the fact that in Python, ordinarily functions are callable, and classes are callable. Leaving apart the mechanisms that mark functions as callable, Python classes have, as you know, special methods. The method that makes instances of a class callable is __call__. So, if your class has an explicit __call__ method, its instances are callable and end of story: when you call the instance, it is the __call__ method that is called.

That answers half your question - now let's check what the __call__ method on the class of classes does.

Classes in Python are themselves also first class objects - but they have to be an instance of type. That is, calling type as one calls a class to create an instance, creates a new class. The Python runtime does this automatically when a class body block is met in code. (but one can also create new classes programmaticaly by explicitly calling type in its three+ parameter form)

As type itself is a subclass of object - its __new__ method is what it has of special, as it creates a new class, filling up all needed data structures as required by the cPython ABI, allocating memory, and putting values into fields that are not accessible from pure Python codes. As it is the class for any kind of class-object in Python it is called a metaclas. One can derive other classes from type and create custom metaclasses, to run code,r insert attributes, register data and so on at the moment classes are created - but that is optional. Any class created goes through type's __new__.

And when you instantiate a class? I wrote above that what makes an object callable in Python is the presence of a __call__ method in its class. type being the class of all classes, it does feature a __call__ method - and it contains the code needed to orchestrate the call to the class' __new__ and __init__ methods. And that is why classes are callable, and why Python can use the same syntax for function calls and object instantiation.

is A.__call__() being called each time I instantiate with A()?

Not properly - what is called is type(A).__call__. A.__call__ and type(A).__call__ will be the same if there is no explict __call__ method defined in A (then its class, type is searched for __call__. But special methods are not called implicitly by Python by ordinary attribute retrieval: they are always picked from the object's class - and that is made inside the runtime.

You might be confused for the metaclass' call not to be available to the class: that is simply not defined like that in the method retrieval algorithms from Python. When you ask for an attribute or method of an object- including a special method like __call__, the class is searched for the attribute in the form a descriptor (to provide custom attribute access) - and then the base classes of that class, but not the class of that class. (Also, for special methods, they are only special if they are defined in the object's class itself: being attached directly to an instance have no effect).

The key document where this is all published is the Python's Data Model - it can take some time and experimenting to figure everything out from there, though.

like image 143
jsbueno Avatar answered Oct 20 '22 22:10

jsbueno


When a __something__ method of an object is called, something like this happens:

  • Does the object's class have it? If so, return.
  • Does its class's superclass have it? If so, return.
  • Does its class's superclass's superclass have it? If so, return.
  • ...

Note that it never looks at the object's class's class.

Since classes are instances of type (or a subclass of it, see here), classes are callable (type has __call__). However, unless the class also defines __call__, its instances won't have it, because it will never look in the class's class.

like image 38
internet_user Avatar answered Oct 20 '22 21:10

internet_user