拦截模块调用?


问题内容

我正在尝试“拦截”对特定模块的所有调用,然后将它们重新路由到另一个对象。我想这样做,以便可以拥有一个相当简单的插件体系结构。

例如,在main.py中

import renderer

renderer.draw('circle')

在renderer.py中

specificRenderer = OpenGLRenderer()

#Then, i'd like to route all calls from main.py so that
#specificRenderer.methodName(methodArgs) is called
# i.e. the above example would call specificRenderer.draw('circle')

这意味着任何函数都可以导入渲染器并使用它,而无需担心细节。这也意味着我可以完全改变渲染器,只需创建另一个对象并将其分配给renderer.py中的“
specificRenderer”值即可。

有任何想法吗?


问题答案:

renderer.py

import sys

if __name__ != "__main__":
    sys.modules[__name__] = OpenGLRenderer()

现在,模块名称已映射到OpenGLRenderer实例,并且import renderer在其他模块中将获得相同的实例。

实际上,您甚至不需要单独的模块。您可以这样做:

import sys
sys.modules["renderer"] = OpenGLRenderer()
import renderer   # gives current module access to the "module"

…主模块中的第一件事。renderer再次导入其他模块将引用同一实例。

您确定真的要首先执行此操作吗?人们并不是期望模块如何行为。