如何为代理 class 动态生成方法?

how to dynamically generate methods for proxy class?

我有一个像这样的对象:

class Foo(object):
    def __init__(self,instance):
        self.instance = instance

>>> instance = SomeOtherObject()
>>> f = Foo(instance)

我希望能够做到

>>> f.some_method()

并进行以下通话,

>>> f.instance.some_method()

由于复杂的原因,我不能像上面那样简单地链接属性。我需要在 f 上动态创建一个实例函数,其函数签名与嵌入式 instance 相同。也就是说,我需要执行 f.some_method(),然后在 f 实例被调用时动态创建 some_method 实例方法,将 some_method 向下推送到嵌入对象 instance

我希望这是有道理的。这是针对 Python 2.7 的。任何帮助表示赞赏。

为您的代理 class 编写一个 __getattr__() 方法。当访问您的实例上不存在的属性时,将调用此方法。 Return 您包含的对象的同名属性(如果您坚持的话,也可以是包装器,但如果您只想调用包含的对象的方法而不需要做任何其他事情,则没有必要)。奖励:适用于数据和可调用对象。

def __getattr__(self, name):
    return getattr(self.instance, name)

但不适用于 __ 方法。

您应该查看 wrapt 模块。它专为创建透明对象代理而构建,您可以在其中有选择地覆盖包装对象的某些方面。例如:

class Test(object):
    def some_method(self):
        print 'original'

import wrapt

proxy = wrapt.ObjectProxy(Test())
proxy.some_method()

print

class TestWrapper(wrapt.ObjectProxy):
    def some_method(self):
        self.__wrapped__.some_method()
        print 'override'

wrapper = TestWrapper(Test())
wrapper.some_method()

这产生:

original

original
override

ObjectProxy class 的默认行为是代理所有方法调用或属性访问。通过代理更新属性也会更新包装的对象。适用于特殊 __ 方法和许多其他内容。

有关 wrapt 的详细信息,请参阅:

关于对象代理的具体细节可以在:

正确执行此操作有很多陷阱,因此建议您尽可能使用 wrapt