Understanding the 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 lookup, but they do very different jobs. The short version is: __getattribute__ runs for every attribute access, while __getattr__ is only a fallback for attributes that were not found normally.
That difference is crucial because __getattribute__ is powerful but easy to break, while __getattr__ is much safer for most dynamic behavior.
__getattr__ Is a Fallback
Python calls __getattr__(self, name) only after normal attribute lookup fails.
Example:
Output:
host is found normally, so __getattr__ is not involved. port is missing, so Python falls back to __getattr__.
This makes __getattr__ a good fit for:
- computed defaults
- lazy attribute creation
- wrappers and proxies
- compatibility shims for old attribute names
__getattribute__ Runs Every Time
Python calls __getattribute__(self, name) for every attribute access, even when the attribute exists.
Example:
This prints the log line even though value exists normally.
That is why __getattribute__ is useful for:
- detailed access control
- tracing and logging
- proxy objects that intercept all reads
- advanced attribute virtualization
But it also means mistakes are much more dangerous.
The Biggest Danger: Infinite Recursion
Inside __getattribute__, if you access self.some_attr directly, that triggers __getattribute__ again and can recurse forever.
Bad version:
This is unsafe because accessing self.__dict__ itself goes through __getattribute__.
Correct version:
The normal pattern is to delegate to super().__getattribute__(name) or object.__getattribute__(self, name).
How They Work Together
The lookup order is roughly:
- call
__getattribute__ - if it finds the attribute, return it
- if it raises
AttributeError, Python may then call__getattr__
That means __getattr__ is not a competitor to __getattribute__. It is a fallback after normal lookup fails.
Example using both:
existing comes from normal lookup. unknown falls through to __getattr__.
When to Use Which One
Use __getattr__ when:
- you only care about missing attributes
- you want a safe default
- you want less risk of breaking normal attribute access
Use __getattribute__ when:
- you truly need to intercept every attribute access
- you are building advanced framework behavior
- you are comfortable handling recursion carefully
For most application code, __getattr__ is the better tool.
A Real-World Example: Proxy Objects
Proxy wrappers often use __getattr__ to delegate unknown attributes to another object.
This is a classic __getattr__ use case because it only needs to handle attributes the proxy does not define itself.
Common Pitfalls
One common mistake is using __getattribute__ when __getattr__ would have been enough. That adds complexity and increases the chance of recursion bugs.
Another mistake is forgetting to raise AttributeError in __getattr__ when an attribute truly does not exist. Python expects missing attributes to behave that way.
It is also easy to break introspection, debugging, and tooling if these methods return surprising values for standard attribute names.
Finally, overusing either method can make ordinary objects harder to reason about. Dynamic attribute tricks are useful, but they should be deliberate.
Summary
- '
__getattribute__runs on every attribute access.' - '
__getattr__runs only when normal lookup fails.' - '
__getattr__is usually safer and better for fallback behavior.' - '
__getattribute__is more powerful but must delegate carefully to avoid infinite recursion.' - Use the simpler hook unless you truly need to intercept all attribute reads.

