2

我正在尝试为另一个类创建一个代理类。我希望将此类传递到其构造函数中的代理中,然后让代理在其自身上动态创建此类的所有相同方法。

这是我到目前为止没有工作的内容:

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 方式来做这件事,我也会很高兴听到这个消息。

4

1 回答 1

5

我不会显式复制包装类的方法。您可以使用魔术方法__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)
于 2017-09-05T10:37:49.087 回答