The intended object should be like this, defining __call__ . The class must be an object ... or at least with some exceptions. This exception is something that I cannot formally clarify, so this question is posted here.
Let A be a simple class:
class A(object): def call(*args): return "In `call`" def __call__(*args): return "In `__call__`"
The first function is intentionally called a “call” to clearly indicate whether the comparison is with another.
Let me create an instance and forget about the expression, which it implies:
a = A()
Now what is worth:
print(A.call()) print(a.call()) print(A()) print(a())
Result:
>>> In `call` >>> In `call` >>> <__main__.A object at 0xNNNNNNNN> >>> In `__call__`
The output (the third statement does not work __call__ ) is not a surprise, but when I think that everyone that says "Python class are objects" ...
This is more explicit, however run __call__
print(A.__call__()) print(a.__call__()) >>> "In `__call__`" >>> "In `__call__`"
All this is just to show how, finally, A() may seem strange.
There are exceptions to the Python rules, but the documentation on the “object. Call ” doesn't say much about __call__ ... nothing more:
3.3.5. Emulating Called Objects
object.__call__(self[, args...])
Called when an instance is "called" as a function; [...]
But how does Python say "it is called as a function" and does this rule honor object.__call__ ?
It may be a type question, but even a type has an object as a base class.
Where can I find out more (and formally) about this?
By the way, is there any difference between Python2 and Python3?
-----% <----- edit ----->% -----
Conclusions and other experiments after one answer and one comment
Update # 1
After @Veedrac's answer and @chepner's comment, I came to this other test that fills in the comments of both:
class M(type): def __call__(*args): return "In `M.__call__`" class A(object, metaclass=M): def call(*args): return "In `call`" def __call__(*args): return "In `A.__call__`" print(A())
Result:
>>> In `M.__call__`
So it seems like a meta class that manages the "call" operations. If I understand correctly, a metaclass does not matter only for the class, but also for class instances.
Update # 2
Another relevant test that shows this is not an attribute of the object that matters, but an attribute of the type of object:
class A(object): def __call__(*args): return "In `A.__call__`" def call2(*args): return "In `call2`" a = A() print(a())
As expected, it prints:
>>> In `A.__call__`
Now this:
a.__call__ = call2 print(a())
He prints:
>>> In `A.__call__`
Same thing before the attribute. It does not print In call2 , it is still In A.__call__ . It is important to note, as well as explain why the __call__ metaclass that was called (remember that the metaclass is a type of class object). __call__ , used to call a function, not from an object, but from its type.