Difference between __getattr__ and __getattribute__
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
__getattr__ and __getattribute__ both participate in attribute access, but they are not interchangeable. The short version is that __getattribute__ runs for every attribute lookup, while __getattr__ runs only as a fallback when normal lookup fails.
How Normal Attribute Lookup Works
When Python evaluates obj.name, it normally searches in this general order:
- instance attributes
- class attributes and descriptors
- inherited attributes
If an attribute is found through the normal machinery, __getattr__ is not called. __getattribute__, however, sits at the front of the process.
__getattribute__: Intercept Every Lookup
If a class defines __getattribute__, Python calls it for every attribute access on the instance.
Output:
This is powerful because you can log, proxy, validate, or compute attributes centrally. It is also dangerous because a careless implementation can recurse forever.
__getattr__: Fallback for Missing Attributes
__getattr__ is called only when the attribute was not found by the normal process.
Here:
- '
obj.languageis found normally, so__getattr__is skipped' - '
obj.versionis missing, so__getattr__supplies a value'
This makes __getattr__ a good tool for defaults, lazy loading, compatibility aliases, and delegated access.
The Biggest Practical Difference
Think of the methods this way:
- '
__getattribute__: "I want to control all attribute access."' - '
__getattr__: "I only care about attributes that do not already exist."'
That difference affects both behavior and maintenance cost. In many cases, __getattr__ is safer because it leaves standard attribute access alone.
Avoiding Infinite Recursion
Inside __getattribute__, you must not access attributes through self.name unless you deliberately want another lookup cycle. Use object.__getattribute__ instead.
Broken version:
This tries to read self.__dict__, which triggers __getattribute__ again, causing recursion.
Correct version:
In __getattr__, recursion is less common because the method runs only after normal lookup fails, but you still need to raise AttributeError for truly missing names. Returning None silently often breaks tools like hasattr and introspection.
Typical Use Cases
Use __getattr__ when:
- you want computed defaults for missing fields
- you are forwarding unknown names to another object
- you are implementing lazy attributes that appear on first access
Use __getattribute__ when:
- you are building a proxy object
- you need to audit every lookup
- you want uniform access control over all attributes
If you do not need that much control, prefer __getattr__. It is easier to reason about and far less likely to interfere with normal object behavior.
Common Pitfalls
The most common mistake is implementing __getattribute__ and then using regular attribute access inside it. That almost always causes infinite recursion unless you route through object.__getattribute__.
Another mistake is forgetting to raise AttributeError in __getattr__ for names you cannot handle. Python expects that exception to mean "attribute really is missing."
A third issue is overusing __getattribute__ when a property, descriptor, or __getattr__ would be enough. Full interception adds complexity and can make debugging awkward.
Finally, people sometimes assume __getattr__ runs for every attribute. It does not. If the attribute exists normally, Python never calls it.
Summary
- '
__getattribute__runs for every attribute access.' - '
__getattr__runs only when normal lookup fails.' - Use
object.__getattribute__inside__getattribute__to avoid recursion. - Use
__getattr__for missing-attribute defaults and delegation. - Prefer the simpler hook unless you truly need total control over lookup behavior.

