- 1 year ago
Adding custom objects ignores __getattr__ with operators
In Python, when custom objects define the __getattr__
method, it allows you to customize attribute access and handle cases where an attribute is not directly defined on the object. However, the __getattr__
method is not invoked for special methods, including operators like +
, -
, *
, etc., which are handled by other special methods like __add__
, __sub__
, __mul__
, etc.
The reason why __getattr__
is not called for operators is that Python uses a specific method resolution order (MRO) to find and execute special methods like __add__
. When Python encounters an operator, it directly looks for the corresponding special method without triggering __getattr__
.
Here's an example to demonstrate this behavior:
pythonclass MyClass:
def __init__(self, value):
self.value = value
def __getattr__(self, name):
print(f'__getattr__ called for attribute "{name}"')
return 42 # A default value for any undefined attribute
def __add__(self, other):
print('__add__ called')
return self.value + other.value
a = MyClass(10)
b = MyClass(20)
# Attribute access, calls __getattr__
print(a.unknown_attribute) # Output: __getattr__ called for attribute "unknown_attribute" 42
# Operator +, calls __add__
result = a + b # Output: __add__ called
print(result) # Output: 30
As you can see in the example, when we access the undefined attribute unknown_attribute
, it triggers the __getattr__
method. However, when we use the +
operator to add two MyClass
objects, it directly calls the __add__
method without invoking __getattr__
.
If you want to customize the behavior of operators like +
for custom objects, you should implement the corresponding special methods (__add__
, __sub__
, etc.) in your class. These special methods are designed to handle specific operator behavior, and you cannot achieve the same effect using __getattr__
.