如何覆盖Python导入? [英] How do I override a Python import?

查看:97
本文介绍了如何覆盖Python导入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发 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.

这个Stack Overflow问题是我到目前为止提供答案的最接近的问题:
Override 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.

希望Stack  Overflow上的某些人比我更了解进口,因为这个让我难过。

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"

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()

这篇关于如何覆盖Python导入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆