猴子补丁导入这个模块

Monkey patch the module that imports this one

因此,我有一个具有此功能的 Python 应用程序,程序目录的 extensions 子目录中的任何类似模块的文件都会在应用程序初始化过程的早期导入。

看起来像这样(假设这是 my_application.py):

def do_init():
    for thefname in glob.iglob(os.path.join(".","extensions","*")):
        SourceFileLoader(os.path.basename(thefname),thefname).load_module()
    #do other init stuff...

if __name__ == "__main__":
    do_init()
    do_cool_things()

现在,我希望能够在该扩展目录中有一个 .py 文件,其内容如下所示:

import my_application
def my_cool_things():
    print("The original things have been overridden.")
my_application.do_cool_things = my_cool_things

这对未来 my_application 的导入有效。但是 if __name__ == "__main__" 守卫内部的 do_cool_things 调用展示了原始行为。为什么会发生这种情况,我怎样才能使该调用表现出修改后的行为?

由 运行 一个名为 my_application.py 的脚本创建的模块令人惊讶地不是 my_application。 运行 脚本创建的模块是 __main__。当然,通过 导入 一个名为 my_application.py 的文件创建的模块将被称为 my_application.

您的问题的两个解决方案是将 import my_application 替换为 import __main__import builtins

简单演示:

#x.py
import y
print ("Hello", hello)

#y.py
import __main__
__main__.hello = 'world'

在 Ubuntu 14.04 上测试 Python 3.4.3:

$ python3 x.py
Hello world
$