自动重定向方法调用并传递调用者
我正在构建一个模块化的应用程序,想让某种类型的所有对象都能调用一个管理对象,并且自动传递它们自己的实例。
场景:
我的应用程序由一个框架和在运行时加载的插件组成。
其中一个插件提供了在每个插件的独立上下文中运行的功能。简单来说:它接收调用插件的实例,并只处理与这个插件相关的数据。
为了避免后面的描述让人困惑,我们把被调用的对象称为管理对象,把调用的对象称为工作对象。
将会有一个管理对象和多个插件:
插件 + : 1 个管理对象
我希望工作对象能够访问管理功能,而不需要在参数列表中明确指定工作实例。
相反,我希望管理方法看起来就像属于工作对象一样,这样调用者的参数传递就变得透明和隐含。
一种可能的方法是,直接在工作类中注册所有新的管理方法。但是,我不喜欢这种“命名空间污染”。我希望它们通过一个属性来访问,这样意义就很明确。
请记住,这种行为是在运行时添加的,我不想修改插件类本身。此外,可能在那时已经实例化了多个插件,但我需要这对所有当前和未来的实例都有效。
我想到的主意是将描述符 __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)
我已经测试过了,似乎可以正常工作。 我在想这种方法是否有任何陷阱,或者是否有更符合 Python 风格的做法。我对描述符的内容还很陌生,可能有些地方没有注意到。
1 个回答
如果你只是想访问一些属性,使用描述符会更好。看起来你正在实现一种类似描述符的设计,但叫它“包装器”。其实,使用描述符可能会更简单,而且和Python中其他使用描述符的地方更一致。
http://docs.python.org/reference/datamodel.html#descriptors
把这个改成一个更典型的描述符类,可能会帮你省一些事。