The documentation lists many magic methods. But I don't think it is enough. It does not tell me what methods are called when I do for x in c
.
To do this, I tried a simple code snippet to print each attribute reference:
class Print(object):
def __getattribute__(self, item):
print(item)
return super().__getattribute__(item)
a = Print()
Sometimes it works:
import pickle
pickle.dumps(a)
# print the following and then raise an error
__reduce_ex__
__reduce__
__getstate__
__class__
Then I know pickle.dump
calls these magic methods.
But sometimes it does not work:
for x in a:
continue
# direct error, no print
Are there any way to tell what magic methods are called in a python statement?
Update:
It seems Cpython bypasses getattribute
calls for some special methods for speedup. Check special-method-lookup section for details.
Therefore, the answer seems to be no. We cannot catch each attribute reference.
Just take this example:
class C:
pass
c = C()
c.__len__ = lambda: 5
len(c)
# TypeError: object of type 'C' has no len()