2017-09-05 51 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)