重定向方法调用并自动传递调用方

时间:2010-11-09 18:09:16

标签: python

我正在构建一个模块化应用程序,我希望某种类型的所有对象能够调用管理对象,并自动传递自己的实例。

方案: 我的应用程序包含一个在运行时加载的框架和插件。 其中一个插件提供了在每个插件的单独上下文中运行的功能。简单地说:它接收调用者插件的实例,并且仅使用与此插件相关联的数据进行操作。 为了避免在以下描述中出现混淆,我们将被调用者称为管理对象,将调用者称为worker对象。 将有一个管理对象和多个插件:
插件+:1管理对象

我希望worker对象能够访问管理功能,而无需在参数列表中明确指定worker实例的实例。

相反,我希望管理方法看起来好像它们属于worker对象 - 这样调用者参数的传递是透明和隐含的。

一种可能性是,直接向工人类注册所有新的管理方法。但是,我不喜欢这种“命名空间污染”。相反,我希望它们可以通过属性访问,以便明确含义。

请记住,此行为是在运行时添加的,我不希望修改Plugin类本身。此外,当时可能已经实例化了多个插件,但我需要这个插件适用于所有当前和未来的实例。

我想出的想法是将描述符__get____getattr__方法组合在一个对象中。

将使用__get__方法来确定调用者的实例。

将使用__getattr__方法来动态包装应该从管理对象调用的方法。

我提出的代码如下:

my_management_object = getItHere()    
class Wrapper(object):
    def __init__(self):
        self._caller = None
     def __getattr__(self, name):
        method = getattr(my_management_object, name)
        def wrapper(*args, **kwargs):
            return method(self._caller, *args, **kwargs)
        return wrapper
     def __get__(self, caller, type):
        self._caller = caller
        return self
MyPluginClass._manage = Wrapper()

现在,我可以这样做:

obj = MyPluginClass()
obj._manage.doSomethingForMe()
#vs:
getMyManagementObject().doSomethingForMe(obj)

我测试了它,似乎有效。 我想知道这种方法是否存在任何陷阱,或者是否有更多的pythonic方法可以做到这一点。我对Descriptor的东西很新,所以我可能忽略了一些东西。

1 个答案:

答案 0 :(得分:0)

如果你正在做的只是访问属性,请使用描述符。您似乎正在实现类似描述符的设计并将其称为“包装器”。描述符可能会稍微简单一些,并且与Python中使用描述符的所有其他位置更加一致。

http://docs.python.org/reference/datamodel.html#descriptors

使这个更典型的描述符类可以为您节省一些工作。