Функции Python и их атрибут __call__

Я использую Python 2.7.2. Я хочу понять взаимосвязь между вызовом функции и вызовом атрибута __call__ функции. Например, рассмотрим следующий код

def foo():
    return 5
print foo()          # ==> 5
print foo.__call__() # ==> 5

foo.__call__ = lambda : 6
print foo()          # ==> 5
print foo.__call__() # ==> 6

Кажется, что первые четыре строки указывают, что вызов функции foo совпадает с вызовом атрибута __call__ foo. Тем не менее, последние три строки, похоже, указывают на то, что они разные звери, поскольку я изменил атрибут __call__, но не изменил значение, возвращаемое вызовом foo().

Может ли кто-нибудь объяснить связь между вызовом foo() и вызовом foo.__call__()? Есть ли способ изменить поведение функции, так что foo(), а также foo.__call__() теперь возвращает 6 вместо 5?

Ответ 1

Я рекомендую вам прочитать специальный поиск методов для классов нового стиля (особенно последний абзац).

Для классов нового стиля неявные вызовы специальных методов только гарантированно работает корректно, если он определен по типу объектов, а не в словаре экземпляров объектов.