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

1 投票
1 回答
2244 浏览
提问于 2025-04-16 06:48

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

场景: 我的应用程序由一个框架和在运行时加载的插件组成。 其中一个插件提供了在每个插件的独立上下文中运行的功能。简单来说:它接收调用插件的实例,并只处理与这个插件相关的数据。 为了避免后面的描述让人困惑,我们把被调用的对象称为管理对象,把调用的对象称为工作对象。 将会有一个管理对象和多个插件:
插件 + : 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 个回答

0

如果你只是想访问一些属性,使用描述符会更好。看起来你正在实现一种类似描述符的设计,但叫它“包装器”。其实,使用描述符可能会更简单,而且和Python中其他使用描述符的地方更一致。

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

把这个改成一个更典型的描述符类,可能会帮你省一些事。

撰写回答