Eva*_*ice 32 python import preprocessor overriding
我正在研究pypreprocessor,这是一个采用c风格指令的预处理器,我已经能够使它像传统的预处理器一样工作(它是自耗的,并且即时执行后处理代码),除了它打破了库进口.
问题是:预处理器运行文件,处理它,输出到临时文件,exec()临时文件.导入的库需要处理稍有不同,因为它们不会被执行,而是被加载并且可以被调用者模块访问.
我需要做的是:中断导入(因为预处理器在导入过程中运行),将后处理代码作为tempModule加载,并用tempModule替换原始导入以欺骗调用脚本认为tempModule是原始模块的导入.
到目前为止,我到处搜索,没有解决方案.
这个Stack Overflow问题是我到目前为止提供答案的最接近的问题: 在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
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
'imp.lock_held'部分检测模块是否作为库加载.以下几行完成其余的工作.
小智 35
这回答了你的问题了吗?第二个导入就是诀窍.
Mod_1.py
def test_function():
print "Test Function -- Mod 1"
Run Code Online (Sandbox Code Playgroud)
Mod_2.py
def test_function():
print "Test Function -- Mod 2"
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
Anu*_*yal 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
Run Code Online (Sandbox Code Playgroud)
它输出:
<__main__.MyImporter object at 0x009F85F0>
Run Code Online (Sandbox Code Playgroud)
所以基本上它返回一个新模块(可以是任何对象),在这种情况下本身.您可以通过返回processe_xxx导入来使用它来改变导入行为xxx.
IMO:Python不需要预处理器.无论你正在完成什么都可以在Python本身完成,因为它非常动态,例如,以调试示例为例,在文件顶部有什么问题
debug = 1
Run Code Online (Sandbox Code Playgroud)
然后
if debug:
print "wow"
Run Code Online (Sandbox Code Playgroud)
?
| 归档时间: |
|
| 查看次数: |
29540 次 |
| 最近记录: |