Topics

Python’s __getattribute__ intercepts all attribute accesses. When implemented incorrectly, it leads to infinite recursion:

class Bad:
    def __init__(self):
        self._dict = {"key1": "value1"}
 
    def __getattribute__(self, name):
        return self._dict[name]  # Recursive call to __getattribute__
 
 
obj = Bad() # throws RecursionError: ...
print(obj.key1)

Solution:

  • Use super().__getattribute__(name) to look in the attribute dictionary
  • For special cases, implement __getattr__ (only called if attribute isn’t found)
class Good:
    def __init__(self):
        self._dict = {"key1": "value1"}
 
    def __getattribute__(self, name):
        return super().__getattribute__("_dict")[name]
 
class GoodToo:
    def __init__(self):
        self._dict = {"key1": "value1"}
 
    def __getattr__(self, name):
        return self._dict[name]
 
obj = Good()
obj2 = GoodToo()
print(obj.key1) # prints: value1
print(obj2.key1) # prints: value1