Python:强制每次导入重新加载

时间:2014-02-27 00:08:08

标签: python metaprogramming python-import monkeypatching

有没有办法强制import x始终在Python中重新加载x(例如,就像我为Python 3调用reload(x)imp.reload(x)一样)?或者一般来说,每次运行import x时是否有某种方法可以强制运行某些代码?我很适合猴子补丁或hackery。

我已尝试将代码移到单独的模块中,并从该单独文件中的x删除sys.modules。我使用了导入钩子,但是我并没有太努力,因为根据文档,只有在检查了sys.modules缓存后才会调用它们。我也尝试使用自定义dict子类进行monkeypatching sys.modules,但每当我这样做时,from module import submodule会引发KeyError(我猜sys.modules不是真正的字典)。

基本上,我正在尝试编写一个调试工具(这就是为什么一些hackery在这里可以)。我的目标只是import x的输入时间短于import x;x.y

2 个答案:

答案 0 :(得分:3)

如果您确实想要更改import语句的语义,则必须修补解释器。 import检查指定的模块是否已加载,如果已加载,则不再执行任何操作。你必须完全改变它,并且在解释器中是硬接线的。

也许您可以使用修补Python源代码来使用myImport('modulename')代替import modulename?这将使其在Python本身内成为可能。

答案 1 :(得分:1)

从Alfe的回答中取得领先,我得到了这样的工作。这是在模块级别。

def custom_logic():
    # Put whatever you want to run when the module is imported here

# This version is run on the first import
custom_logic()

def __myimport__(name, *args, **kwargs):
    if name == 'x': # Replace with the name of this module
        # This version is run on all subsequent imports
        custom_logic()
    return __origimport__(name, *args, **kwargs)

# Will only be run on first import
__builtins__['__origimport__'] = __import__
__builtins__['__import__'] = __myimport__

我们是monkeypatching __builtins__,这就是__origimport__运行时定义__myimport__的原因。