我正在研究pypreprocessor这是一个采用c风格指令的预处理器,我已经能够使它像传统的预处理器一样工作(它是自我消耗的并且在上面执行后处理代码)除了它打破了图书馆的进口外。
问题是:预处理器运行文件,处理它,输出到临时文件,exec()临时文件。导入的库需要处理稍微不同,因为它们不会被执行,而是被加载并且可以被调用者模块访问。
我需要做的是:中断导入(因为预处理器在导入过程中运行),将后处理代码作为tempModule加载,并将原始导入替换为tempModule以欺骗调用脚本导入,认为tempModule是原始模块。
到目前为止,我到处搜索并且没有解决方案。
这个Stack Overflow问题是我到目前为止提供答案的最接近的问题: 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是后处理代码文件的名称。
奇怪的是这个解决方案仍然完全正常运行,好像第一个模块完成正常加载一样;除非删除最后一行,否则会出现模块未找到错误。
希望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'部分检测模块是否作为库加载。以下几行完成其余的工作。
答案 0 :(得分:35)
这是否回答了你的问题?第二个导入就是诀窍。
Mod_1.py
def test_function():
print "Test Function -- Mod 1"
Mod_2.py
def test_function():
print "Test Function -- Mod 2"
Test.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()
答案 1 :(得分:12)
要定义不同的导入行为或完全破坏导入过程,您需要编写导入钩子。请参阅PEP 302。
例如,
import sys
class MyImporter(object):
def find_module(self, module_name, package_path):
# Return a loader
return self
def load_module(self, module_name):
# Return a module
return self
sys.meta_path.append(MyImporter())
import now_you_can_import_any_name
print now_you_can_import_any_name
输出:
<__main__.MyImporter object at 0x009F85F0>
所以基本上它返回一个新模块(可以是任何对象),在这种情况下本身。您可以通过在导入processe_xxx
时返回xxx
来改变导入行为。
IMO:Python不需要预处理器。无论你正在完成什么,都可以在Python本身完成,因为它非常动态,例如,以调试示例为例,在文件顶部有什么问题
debug = 1
以后
if debug:
print "wow"
答案 2 :(得分:1)
在Python 2中,imputil
模块似乎提供了您正在寻找的功能,但已在python 3中删除。它没有很好的文档,但包含一个示例部分,说明如何替换标准导入功能。
对于Python 3,有importlib
模块(在Python 3.1中引入),其中包含用于以各种方式修改导入功能的函数和类。将预处理器挂钩到导入系统应该是合适的。
答案 3 :(得分:-3)
非常奇怪的方法 - 用高级语言模拟低级语言。如果第一种简单的方法不起作用,可能是一个错误的目标?
BTW,C预处理器只使用文本文件和一组预处理器变量,而不是高级加载/卸载模块。