我有一个像这样的对象:
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()
,然后在some_method
实例被调用时将动态创建f
实例方法,将some_method
向下推送到嵌入对象{ {1}}。
我希望这是有道理的。这适用于Python 2.7。任何帮助表示赞赏。
答案 0 :(得分:3)
为您的代理类编写__getattr__()
方法。当访问在您的实例上不存在的属性时,将调用此方法。返回您所包含的同名对象的属性(如果您坚持,则返回包装器,但如果您只是想调用所包含的对象的方法并且不需要,则不需要做其他事情)。奖励:适用于数据和可调用的内容。
def __getattr__(self, name):
return getattr(self.instance, name)
但不适用于__
方法。
答案 1 :(得分:1)
您应该查看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
类的默认行为是代理所有方法调用或属性访问。通过代理更新属性也将更新包装对象。适用于特殊的__
方法以及许多其他方法。
有关wrapt
的详细信息,请参阅:
有关对象代理的具体详情,请参阅:
正确执行此操作有很多陷阱和陷阱,因此建议您尽可能使用wrapt
。