2017-09-05 41 views
0

我試圖創建一個代理類到另一個類。我希望這個類在其構造函數中被傳遞到代理中,然後讓代理動態地爲它自己創建這個類的所有方法。Python代理類

這是我hvae到目前爲止,這是行不通的:

import inspect 
from optparse import OptionParser 

class MyClass: 

    def func1(self): 
     print 'MyClass.func1' 


    def func2(self): 
     print 'MyClass.func1' 


class ProxyClass: 

    def __init__(self): 
     myClass = MyClass() 
     members = inspect.getmembers(MyClass, predicate=inspect.ismethod) 
     for member in members: 
      funcName = member[0] 
      def fn(self): 
       print 'ProxyClass.' + funcName 
       return myClass[funcName]() 
      self.__dict__[funcName] = fn 

proxyClass = ProxyClass() 
proxyClass.func1() 
proxyClass.func2() 

我認爲這是一個需要改變線路self.__dict__[funcName] = fn但我不知道什麼?

我是新來的Python,所以如果有一個完全不同的Pythonic這樣做的方式,我也很樂意聽到這一點。

+0

你還沒有說過它是如何「不工作」。你爲什麼認爲字典的任務需要改變?不過,這是一個奇怪的方法。是否有任何理由不想通過重寫'__getattr__'來完成委託調用? –

+0

當前錯誤是當我調用proxyClass.func1()我說它需要採取1參數,這表明該函數沒有正確放在實例 – user2802557

+0

使用代理模式的整個前提是創建一個類,簡化/限制等。與原始類的交互,所以只是想知道爲什麼你試圖複製成員。即使你需要1:1屬性和成員訪問代理,爲什麼不只是傳遞你的類到代理構造函數,並將它分配給像self.subject這樣的東西? –

回答

4

我不會明確複製包裝類的方法。您可以使用魔術方法__getattr__來控制在代理對象上調用某些內容時發生的情況,包括根據需要進行裝飾; __getattr__必須返回一個可調用對象,因此您可以使該可調用對象執行您所需的任何操作(除了調用原始方法外)。

我在下面包含了一個例子。

class A: 
    def foo(self): return 42 
    def bar(self, n): return n + 5 
    def baz(self, m, n): return m ** n 

class Proxy: 
    def __init__(self, proxied_object): 
     self.__proxied = proxied_object 

    def __getattr__(self, attr): 
     def wrapped_method(*args, **kwargs): 
      print("The method {} is executing.".format(attr)) 
      result = getattr(self.__proxied, attr)(*args, **kwargs) 
      print("The result was {}.".format(result)) 
      return result  
     return wrapped_method 

proxy = Proxy(A()) 
proxy.foo() 
proxy.bar(10) 
proxy.baz(2, 10)