2016-08-05 63 views
0

我有一個對象,如:如何動態生成代理類的方法?

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

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

我希望能夠做

>>> f.some_method() 

,並有下列呼叫,

>>> f.instance.some_method() 

對於com有些問題,我不能簡單地把上面的屬性鏈接起來。我需要在f上動態創建一個實例函數,其功能簽名與嵌入的instance相同。也就是說,我需要執行f.some_method(),然後在調用實例時動態創建some_method實例方法,該方法將some_method向下推入嵌入對象instance

我希望這是有道理的。這是爲Python 2.7。任何幫助讚賞。

+0

要在你的代碼中創建一個'Foo',你必須通過一個其他的實例作爲參數,所以'f = Foo()'會導致錯誤。 – martineau

回答

3

爲您的代理類寫一個__getattr__()方法。當訪問實例中不存在的屬性時,將調用此方法。返回你的包含對象的同名屬性(或者如果你堅持要包裝的話,但是如果你只是想調用包含對象的方法而不需要做其他事情)。獎金:適用於數據以及可調參數。

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

但是,不適用於__方法。

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,如果可以的話。