将“__getattr__”方法添加到现有对象实例



我希望这样做:

import types
def new_getattr(self, *args, **kwargs):
    return 2
class A:
    def __init__(self):
        pass
a = A()
a.__getattr__ = types.MethodType(new_getattr, a)
print(a.anything)

现在,它抛出了AttributeError: A instance has no attribute 'anything'.

我尝试了这里提出的不同解决方案,它们有效,但不适用于__getattr__.

如果我做print(a.__getattr__('anything')),它实际上打印2;问题是当我做a.anything时,我的__getattr__方法没有自动调用。


作为旁注,在我的实际实现中,我不能修改类A的定义,也不能键入它的名称并做类似 A.__getattr__ = ... 的操作(这将起作用(,因为我需要它是通用的并且独立于类名。

编辑:我最终这样做了:

a.__class__.__getattr__ = new_getattr .

你不能 - __dunder__名称在类型上解析,而不是按实例解析。自定义__getattr__需要直接在A上定义。

请参阅数据模型文档的特殊方法查找部分,具体为:

对于自定义类,只有在对象的类型上定义而不是在对象的实例字典中定义时,才能保证对特殊方法的隐式调用正常工作。

注意:如果你只有一个对实例的引用,而不是对类的引用,仍然可以通过将方法赋值到type(a)返回的对象上来对类型进行猴子修补。 请注意,这将影响所有现有实例,而不仅仅是a实例。

最新更新