I have the following class:
class MyInt:
def __init__(self, v):
if type(v) != int:
raise ValueError('value must be an int')
self.v = v
def __getattr__(self, attr):
return getattr(self.v, attr)
i = MyInt(0)
print(i + 1)
I get the error: TypeError: unsupported operand type(s) for +: 'MyInt' and 'int'
Shouldn't i.__add__(1)
be called? And shouldn't __getattr__
be called when no such method is found in the MyInt
class?
Okay, so it's cool that you can use getattr to get methods as well as properties, but how does that help us? Well, this can definitely be useful in keeping your code DRY if you have some common logic surrounding branching method calls.
Python getattr() function is used to get the value of an object's attribute and if no attribute of that object is found, default value is returned.
Python getattr() function is used to access the attribute value of an object and also gives an option of executing the default value in case of unavailability of the key. Parameters : obj : The object whose attributes need to be processed. key : The attribute of object.
The getattr() method returns the value of the named attribute of an object. If not found, it returns the default value provided to the function.
__getattr__
cannot be used to generate other magic methods. You'll need to implement all of them individually.
When the Python language internals look up magic methods like __add__
, they completely bypass __getattr__
, __getattribute__
, and the instance dict. The lookup goes roughly like
def find_magic_method(object, method_name):
for klass in type(object).__mro__:
if method_name in klass.__dict__:
return klass.__dict__[method_name]
raise AttributeError
If you want to see the exact lookup procedure, it's _PyObject_LookupSpecial
in Objects/typeobject.c
.
If you're wondering why Python does this, there are a lot of magic methods for which it would be really awkward or impossible to do what you were expecting. For example, Python couldn't possibly use __getattribute__
to look up __getattribute__
, as that would cause infinite recursion with no base case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With