Python - 覆盖实例的__getattribute__?

时间:2009-10-13 15:08:51

标签: python django

这对我来说似乎有点棘手。前段时间我已经设法用以下内容覆盖实例的方法:

def my_method(self, attr):
    pass

instancemethod = type(self.method_to_overwrite)
self.method_to_overwrite = instancemethod(my_method, self, self.__class__)

对我来说效果很好;但是现在我试图覆盖一个实例的__getattribute__()函数,由于该方法似乎是

,这对我不起作用
<type 'method-wrapper'>

有可能对此做些什么吗?我在method-wrapper上找不到任何合适的Python文档。

4 个答案:

答案 0 :(得分:5)

您想要基于每个实例覆盖属性查找算法吗?在不知道你为什么要这样做的情况下,我会猜测有一种更清洁,更少复杂的方式来做你需要做的事情。如果你真的需要像Aaron所说的那样,你需要在类上安装一个重定向__getattribute__处理程序,因为Python只在类上查找特殊方法,忽略在实例上定义的任何东西。

您还必须格外小心,不要进入无限递归:

class FunkyAttributeLookup(object):
    def __getattribute__(self, key):
        try:
            # Lookup the per instance function via objects attribute lookup
            # to avoid infinite recursion.
            getter = object.__getattribute__(self, 'instance_getattribute')
            return getter(key)
        except AttributeError:
            return object.__getattribute__(self, key)

f = FunkyAttributeLookup()
f.instance_getattribute = lambda attr: attr.upper()
print(f.foo) # FOO

另外,如果要覆盖实例上的方法,则不需要自己实例化方法对象,可以在生成方法的函数上使用描述符协议,也可以只调用self参数。

 #descriptor protocol
 self.method_to_overwrite = my_method.__get__(self, type(self))
 # or curry
 from functools import partial
 self.method_to_overwrite = partial(my_method, self)

答案 1 :(得分:3)

有两种方法无法覆盖,__getattribute__()就是其中之一。

答案 2 :(得分:3)

答案 3 :(得分:1)

我相信 method-wrapper 是用C编写的方法的包装。