【问题标题】:Python proxy classPython 代理类
【发布时间】:2018-02-13 14:49:21
【问题描述】:

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

这是我目前为止无法使用的:

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 方式来做这件事,我也很乐意听到。

【问题讨论】:

  • 你还没有说它是如何“不工作”的。为什么你认为 dict 分配需要改变?然而,这是一种奇怪的方法。您是否有任何理由不想简单地通过覆盖 __getattr__ 来委派调用?
  • 当前错误是当我调用 proxyClass.func1() 时,我说它需要接受 1 个参数,这表明该函数尚未正确放置在实例上
  • 使用代理模式的整个前提是创建一个简化/限制等的类。与原始类的交互,所以只是想知道为什么您要尝试仅复制成员。即使您在代理中需要 1:1 属性和成员访问,为什么不将您的类传递给代理构造函数并将其分配给 self.subject 之类的东西?
  • 我不确定您将其分配给 self.subject 的确切含义以及这将有何帮助?

标签: python proxy-pattern


【解决方案1】:

我不会显式复制包装类的方法。您可以使用魔术方法__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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多