如何覆盖Python的导入?
如何覆盖Python的导入?
我正在开发一个名为pypreprocessor的预处理器,它可以接受C风格的指令。我已经成功将其运作得像传统的预处理器一样(它是自消耗的,并且可以实时执行后处理的代码),只是它会破坏库的导入。
问题是:预处理器会遍历文件,进行处理,输出到一个临时文件,然后使用exec()执行临时文件。导入的库需要稍微处理一下,因为它们不会被执行,而是载入并使其对调用模块可访问。
我需要做的是:中断导入(因为预处理器在导入过程中运行),将后处理的代码作为临时模块加载,并将原始导入替换为临时模块,以欺骗调用脚本的导入部分,使其认为临时模块是原始模块。
我已经到处搜索了,但是目前还没有找到解决方案。
这个Stack Overflow的问题是我目前看到的最接近提供答案的:
这是我的代码。
# 删除第一个导入创建的字节码文件 os.remove(moduleName + '.pyc') # 删除第一个导入 del sys.modules[moduleName] # 导入后处理的模块 tmpModule = __import__(tmpModuleName) # 将第一个模块的引用指向预处理的模块 sys.modules[moduleName] = tmpModule
moduleName是原始模块的名称,tmpModuleName是后处理代码文件的名称。
奇怪的是,这个解决方案仍然完全正常运行,就好像第一个模块正常加载完成一样;除非删除最后一行,然后会出现模块找不到的错误。
希望Stack Overflow上的某个人在导入方面比我更了解,因为这个问题让我困惑。
注意:我只会授予一个解决方案,或者如果在Python中不可能实现的话,提供最好、最详细的解释。
更新:对于任何感兴趣的人,这是可行的代码。
if imp.lock_held() is True: del sys.modules[moduleName] sys.modules[tmpModuleName] = __import__(tmpModuleName) sys.modules[moduleName] = __import__(tmpModuleName)
'imp.lock_held'部分检测模块是否作为库加载。接下来的几行完成剩下的工作。