2016-08-05 14 views
0

Ich habe ein Objekt wie:wie dynamisch Methoden für die Proxy-Klasse generieren?

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

mit

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

Ich möchte

>>> f.some_method() 

tun zu können und haben den folgenden Aufruf,

>>> f.instance.some_method() 

Für com Aus Gründen kann ich die Attribute nicht einfach wie oben verketten. Ich muss eine Instanzfunktion auf f mit der gleichen Funktionssignatur wie das eingebettete instance dynamisch erstellen. Das heißt, ich muss f.some_method() machen und dann dynamisch die Instanz-Methode some_method für die f Instanz erstellen, wenn sie aufgerufen wird, die some_method auf das eingebettete Objekt instance herunterdrückt.

Ich hoffe, dass es Sinn gemacht. Dies ist für Python 2.7. Jede Hilfe wird geschätzt.

+0

Um ein "Foo" in Ihrem Code zu erstellen, muss eine Instanz von etwas anderem als Argument übergeben werden, so dass 'f = Foo()' einen Fehler verursachen würde. – martineau

Antwort

3

Schreiben Sie eine __getattr__() Methode für Ihre Proxy-Klasse. Dies wird aufgerufen, wenn auf ein Attribut zugegriffen wird, das in Ihrer Instanz nicht vorhanden ist. Geben Sie das Attribut des enthaltenen Objekts mit demselben Namen zurück (oder einen Wrapper, wenn Sie darauf bestehen, aber es ist nicht notwendig, dass Sie nur die Methode des enthaltenen Objekts aufrufen und nichts anderes tun möchten). Bonus: arbeitet mit Daten sowie Callables.

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

Funktioniert jedoch nicht mit __ Methoden.

1

Sie sollten sich das Modul wrapt ansehen. Es ist speziell für das Erstellen eines transparenten Objekt-Proxies konzipiert, in dem Sie bestimmte Aspekte des eingepackten Objekts selektiv überschreiben können. Zum Beispiel:

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() 

Dies ergibt:

original 

original 
override 

Das Standardverhalten der ObjectProxy Klasse Proxy alle Methodenaufrufe oder Zugriffsattribut. Das Aktualisieren von Attributen über den Proxy aktualisiert auch das umgebrochene Objekt. Funktioniert für spezielle __ Methoden und viele andere Sachen.

Einzelheiten zu wrapt siehe:

Spezifische Details über das Objekt-Proxy finden Sie in:

Es gibt so viele Fallen und Fallstricke, wenn Sie das richtig machen, also sollten Sie wrapt verwenden, wenn Sie können.