This question already has answers here:
Closed 7 years ago.
Possible Duplicate:
Intercept operator lookup on metaclass
How can I intercept calls to python’s “magic” methods in new style classes?
Consider the following code:
class ClassA(object):
def __getattribute__(self, item):
print 'custom__getattribute__ - ' + item
return ''
def __str__(self):
print 'custom__str__'
return ''
a=ClassA()
print 'a.__str__: ',
a.__str__
print 'str(a): ',
str(a)
The output was surprising to me:
a.__str__: custom__getattribute__ - __str__
str(a): custom__str__
- Isn't
str(a)
supposed to be mapped to the magic method
a.__str__()
?
- If I remove the custom
ClassA.__str__()
, then
ClassA.__getattribute__()
still doesn't catch the call. How come?
As linked by user1579844 what is happening is that the new-style classes avoid the normal lookup mechanism of __getattribute__ and load directly the method when the interpreter call them. This is done for performance reasons, being the magic method so common that the standard lookup would slow down terribly the system.
When you explicitly call them with the dot notation you are falling back to the standard lookup and so you call the __getattribute__ first.
If you are working in python 2.7 you can avoid this behavior using old style classes, otherwise look to the answers in the thread suggested to find some solution.
when you called
a.__str__
it was considered
__str__
as item in the constructor .
def __getattribute__(self, item):
print 'custom__getattribute__ - ' + item
return ''
in this line :
print 'custom__getattribute__ - ' + item