What happens when a __call__ function is defined in both class and object ?
Chris Angelico
rosuav at gmail.com
Thu Oct 19 04:26:57 EDT 2017
On Thu, Oct 19, 2017 at 7:24 PM, Chris Angelico <rosuav at gmail.com> wrote:
> On Thu, Oct 19, 2017 at 7:11 PM, ast <nomail at com.invalid> wrote:
>> Hello, please have a look at following code snippet
>> (python 3.4.4)
>>
>> class Test:
>>
>> a = 1
>>
>> def __init__(self):
>> self.a = 2
>> self.f = lambda : print("f from object")
>> self.__call__ = lambda : print("__call__ from object")
>> def __call__(self):
>> print("__call__ from class Test")
>> def f(self):
>> print("f from class Test")
>>
>> test=Test()
>>
>>>>> test.a
>>
>> 2
>> ok, a is defined in both the class and the object, it is read from
>> the object. This is the expected behavior
>>
>>>>> test.f()
>>
>> f from object
>>
>> ok for the same reason
>>
>>>>> test()
>>
>> __call__ from class Test
>>
>>
>> Surprisingly, __call__ from the class is called, not the
>> one defined in the object. Why ?
>
> That's the way most dunder methods (those with "d"ouble "under"scores
> before and after their names) work.
Oops, premature send, sorry!
Dunder methods are looked up on the class. In the extremely rare
situation where you want a per-instance customization, you can do it
yourself with something like this:
class Test:
def __call__(self):
if hasattr(self, "spam_handler"):
return self.spam_handler()
return generic_spam_handler()
It's more efficient if, most of the time, the instance dict is skipped
and the search starts with the class.
ChrisA
More information about the Python-list
mailing list