getting rid of the recursion in __getattribute__
A KR
alicpp at gmail.com
Wed May 24 09:37:31 EDT 2023
It is perfectly explained in the standards here [1] saying that:
<quote>
In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.__getattribute__(self, name).
</quote>
Therefore, I wrote a code following what the standard says:
<code>
class Sample():
def __init__(self):
self.a = -10
def __getattribute__(self, name):
if name == 'a':
return object.__getattribute__(self, name)
raise AttributeError()
s = Sample()
result = s.a
print(result)
</code>
I did not fall into recursion, and the output was
-10
I used here object.__getattribute__(self, name) cause the base class of Sample is object.
If I derive the Sample class from another class such as A, I should change object.__getattribute__(self, name) to A.__getattribute__(self, name) as the base class of class Sample is class A.
<code>
class A:
pass
class Sample(A):
def __init__(self):
self.a = -10
def __getattribute__(self, name):
if name == 'a':
return A.__getattribute__(self, name)
raise AttributeError()
s = Sample()
result = s.a
print(result)
</code>
which gives the same output as expected. No recursion and -10.
However, when I try the code without deriving from a class:
class AnyClassNoRelation:
pass
class Sample():
def __init__(self):
self.a = -10
def __getattribute__(self, name):
if name == 'a':
return AnyClassNoRelation.__getattribute__(self, name)
raise AttributeError()
s = Sample()
result = s.a
print(result)
and calling __getattribute__ via any class (in this example class AnyClassNoRelation) instead of object.__getattribute__(self, name) as the standard says call using the base class, I get the same output: no recursion and -10.
So my question:
How come this is possible (having the same output without using the base class's __getattribute__? Although the standards clearly states that __getattribute__ should be called from the base class.
<quote>
In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.__getattribute__(self, name).
</quote>
Literally, I can call __getattribute__ with anyclass (except Sample cause it will be infinite recursion) I define and it works just fine. Could you explain me why that happens?
[1] https://docs.python.org/3/reference/datamodel.html#object.__getattribute__
More information about the Python-list
mailing list