Chamada de função e o atributo __call__
Os callables do Python são objetos que possuem um__call__
método. Na maioria das vezes, são funções, mas também podem ser instâncias de classe.
Mas acontece que as funções têm um__call__
método. Portanto, um__call__
método tem um__call__
método também. A sessão REPL a seguir mostra que podemos encadear o__call__
s:
>>> print
<built-in function print>
>>> print.__call__
<method-wrapper '__call__' of builtin_function_or_method object at 0x0000025E2D597F78>
>>> print.__call__.__call__
<method-wrapper '__call__' of method-wrapper object at 0x0000025E2F631438>
>>> print.__call__.__call__.__call__
<method-wrapper '__call__' of method-wrapper object at 0x0000025E2F5F85F8>
>>> print.__call__.__call__.__call__.__call__
<method-wrapper '__call__' of method-wrapper object at 0x0000025E2F725DA0>
... e assim por diante. Notavelmente, todos esses métodos têm endereços diferentes. Além disso, todos eles têm o mesmo comportamento:
>>> print("a")
a
>>> print.__call__("a")
a
>>> print.__call__.__call__("a")
a
>>> print.__call__.__call__.__call__("a")
Então, quando eu escrevoprint("a")
, como é realmente chamado? É issoprint
ouprint.__call__
? E se eu definir umFoo
aula com um__call__
método?
Além disso, como é possível que todos os__call__
método tem seu própriodiferente __call__
método? Será que eles foram criados quando tentei acessá-los?