问题描述
我正在研究 pypreprocessor 这是一个采用 c 风格指令和我已经能够让它像传统的预处理器一样工作(它是自我消耗的,并在运行中执行后处理代码),只是它会破坏库导入.
I'm working on pypreprocessor which is a preprocessor that takes c-style directives and I've been able to make it work like a traditional preprocessor (it's self-consuming and executes postprocessed code on-the-fly) except that it breaks library imports.
问题是:预处理器遍历文件,处理它,输出到一个临时文件,然后exec()临时文件.导入的库需要稍微不同的处理,因为它们不会被执行,而是被加载并可供调用者模块访问.
The problem is: The preprocessor runs through the file, processes it, outputs to a temporary file, and exec() the temporary file. Libraries that are imported need to be handled a little different, because they aren't executed, but rather they are loaded and made accessible to the caller module.
我需要做的是:中断导入(因为预处理器在导入过程中运行),将后处理代码加载为 tempModule,并用 tempModule 替换原始导入以欺骗使用导入调用脚本以相信 tempModule 是原始模块.
What I need to be able to do is: Interrupt the import (since the preprocessor is being run in the middle of the import), load the postprocessed code as a tempModule, and replace the original import with the tempModule to trick the calling script with the import into believing that the tempModule is the original module.
到目前为止,我已经到处搜索,但没有解决方案.
I have searched everywhere and so far and have no solution.
这个堆栈溢出问题是迄今为止我见过的最接近提供答案的问题:覆盖 Python 中的命名空间
This Stack Overflow question is the closest I've seen so far to providing an answer:Override namespace in Python
这是我所拥有的.
# Remove the bytecode file created by the first import
os.remove(moduleName + '.pyc')
# Remove the first import
del sys.modules[moduleName]
# Import the postprocessed module
tmpModule = __import__(tmpModuleName)
# Set first module's reference to point to the preprocessed module
sys.modules[moduleName] = tmpModule
moduleName 是原始模块的名称,tmpModuleName 是后处理代码文件的名称.
moduleName is the name of the original module, and tmpModuleName is the name of the postprocessed code file.
奇怪的是,这个解决方案仍然完全正常运行,就好像第一个模块正常加载完成一样;除非你删除最后一行,否则你会得到一个找不到模块的错误.
The strange part is this solution still runs completely normal as if the first module completed loaded normally; unless you remove the last line, then you get a module not found error.
希望 StackOverflow 上的某个人比我更了解导入,因为这个让我难住了.
Hopefully someone on Stack Overflow know a lot more about imports than I do, because this one has me stumped.
注意:我只会奖励一个解决方案,或者,如果这在 Python 中是不可能的;关于为什么这不是不可能的最好、最详细的解释.
更新:对于任何感兴趣的人,这里是工作代码.
if imp.lock_held() is True:
del sys.modules[moduleName]
sys.modules[tmpModuleName] = __import__(tmpModuleName)
sys.modules[moduleName] = __import__(tmpModuleName)
'imp.lock_held' 部分检测模块是否作为库加载.以下几行完成剩下的工作.
The 'imp.lock_held' part detects whether the module is being loaded as a library. The following lines do the rest.
推荐答案
这是否回答了您的问题?第二个导入可以解决问题.
Does this answer your question? The second import does the trick.
Mod_1.py
def test_function():
print "Test Function -- Mod 1"
Mod_2.py
def test_function():
print "Test Function -- Mod 2"
测试.py
#!/usr/bin/python
import sys
import Mod_1
Mod_1.test_function()
del sys.modules['Mod_1']
sys.modules['Mod_1'] = __import__('Mod_2')
import Mod_1
Mod_1.test_function()
这篇关于如何覆盖 Python 导入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!