How to use __getattr__ to delegate methods to attribute?

Deadly 提交于 2020-01-15 06:27:49

问题


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?


回答1:


__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.



来源:https://stackoverflow.com/questions/38294904/how-to-use-getattr-to-delegate-methods-to-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!