In addition to bypassing any instance attributes in the interest of correctness, implicit special method lookup generally also bypasses the
__getattribute__()
method even of the object’s metaclass.
The docs mention special methods such as __hash__
, __repr__
and __len__
, and I know from experience it also includes __iter__
for Python 2.7.
To quote an answer to a related question:
"Magic
__methods__()
are treated specially: They are internally assigned to "slots" in the type data structure to speed up their look-up, and they are only looked up in these slots."
In a quest to improve my answer to another question, I need to know: Which methods, specifically, are we talking about?
Checked in 2.7.9
Couldn't find any way to bypass the call to __getattribute__
, with any of the magical methods that are found on object
or type
:
# Preparation step: did this from the console
# magics = set(dir(object) + dir(type))
# got 38 names, for each of the names, wrote a.<that_name> to a file
# Ended up with this:
a.__module__
a.__base__
#...
Put this at the beginning of that file, which i renamed into a proper python module (asdf.py)
global_counter = 0
class Counter(object):
def __getattribute__(self, name):
# this will count how many times the method was called
global global_counter
global_counter += 1
return super(Counter, self).__getattribute__(name)
a = Counter()
# after this comes the list of 38 attribute accessess
a.__module__
#...
a.__repr__
#...
print global_counter # you're not gonna like it... it printer 38
Then i also tried to get each of those names by getattr
and hasattr
-> same result. __getattribute__
was called every time.
So if anyone has other ideas... I was too lazy to look inside C code for this, but I'm sure the answer lies somewhere there.
So either there's something that i'm not getting right, or the docs are lying.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With