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__ -- https://mail.python.org/mailman/listinfo/python-list