如何使用__getattr__将方法委托给属性?
How to use __getattr__ to delegate methods to attribute?
我有以下 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)
我收到错误:TypeError: unsupported operand type(s) for +: 'MyInt' and 'int'
不应该调用i.__add__(1)
吗?当在 MyInt
class 中找不到这样的方法时,不应该调用 __getattr__
吗?
__getattr__
不能用来生成其他法术。您需要单独实施所有这些。
当 Python 语言内部查找像 __add__
这样的魔术方法时,它们会完全绕过 __getattr__
、__getattribute__
和实例字典。查找大致像
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
如果您想查看确切的查找过程,请在 Objects/typeobject.c
中查看 _PyObject_LookupSpecial
。
如果您想知道为什么 Python 这样做,有很多神奇的方法可能会非常尴尬或无法完成您期望的事情。例如,Python 不可能使用 __getattribute__
来查找 __getattribute__
,因为那样会导致没有基本情况的无限递归。
我有以下 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)
我收到错误:TypeError: unsupported operand type(s) for +: 'MyInt' and 'int'
不应该调用i.__add__(1)
吗?当在 MyInt
class 中找不到这样的方法时,不应该调用 __getattr__
吗?
__getattr__
不能用来生成其他法术。您需要单独实施所有这些。
当 Python 语言内部查找像 __add__
这样的魔术方法时,它们会完全绕过 __getattr__
、__getattribute__
和实例字典。查找大致像
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
如果您想查看确切的查找过程,请在 Objects/typeobject.c
中查看 _PyObject_LookupSpecial
。
如果您想知道为什么 Python 这样做,有很多神奇的方法可能会非常尴尬或无法完成您期望的事情。例如,Python 不可能使用 __getattribute__
来查找 __getattribute__
,因为那样会导致没有基本情况的无限递归。