在交互时重新导入模块

如何重新导入模块?我想在对其.py文件进行更改后重新导入一个模块。

272485 次浏览

# EYZ0:

import importlib
importlib.reload(nameOfModule)

# EYZ0:

reload(my.module)

Python文档

重新加载以前导入的模块。参数必须是一个模块对象,因此它必须之前已成功导入。如果您已经使用外部编辑器编辑了模块源文件,并且希望在不离开Python解释器的情况下试用新版本,那么这很有用。

不要忘记使用这种方法的注意事项:

  • 当一个模块被重新加载时,它的字典(包含该模块的全局变量)将被保留。名称的重新定义将覆盖旧的定义,所以这通常不是问题,但如果模块的新版本没有定义由旧版本定义的名称,则旧的定义不会被删除。

  • 如果一个模块使用from ... import ...从另一个模块导入对象,为另一个模块调用reload()不会重定义从它导入的对象——一种方法是重新执行from语句,另一种方法是使用import和限定名称(module.*name*)。

  • 如果一个模块实例化了一个类的实例,重新加载定义该类的模块不会影响实例的方法定义——它们继续使用旧的类定义。派生类也是如此。

在python 3中,reload不再是一个内置函数。

如果你使用的是python 3.4+,你应该使用importlib库中的reload:

import importlib
importlib.reload(some_module)

如果你使用的是python 3.2或3.3,你应该:

import imp
imp.reload(module)

代替。看到# EYZ0

如果你正在使用ipython,一定要考虑使用autoreload扩展:

%load_ext autoreload
%autoreload 2

实际上,在python3中,模块imp被标记为DEPRECATED。至少3.4是这样的。

相反,应该使用importlib模块中的reload函数:

< a href = " https://docs.python.org/3/library/importlib.html importlib.reload " > https://docs.python.org/3/library/importlib.html importlib.reload < / >

但是请注意,这个库在上两个小版本中有一些api更改。

虽然提供的答案确实适用于特定的模块,但它们不会重载子模块,正如这个答案中所指出的:

如果一个模块使用from ... import ...从另一个模块导入对象,为另一个模块调用reload()不会重定义从它导入的对象——一种方法是重新执行from语句,另一种方法是使用import和限定名称(module.*name*)。

但是,如果使用__all__变量来定义公共API,则可以自动重载所有公共可用的模块:

# Python >= 3.5
import importlib
import types




def walk_reload(module: types.ModuleType) -> None:
if hasattr(module, "__all__"):
for submodule_name in module.__all__:
walk_reload(getattr(module, submodule_name))
importlib.reload(module)




walk_reload(my_module)

在前面的回答中提到的警告仍然有效。值得注意的是,修改不属于__all__变量所描述的公共API的子模块不会受到使用该函数重新加载的影响。类似地,删除子模块的元素不会被重新加载反映出来。

如果你想从一个模块中导入一个特定的函数或类,你可以这样做:

import importlib
import sys
importlib.reload(sys.modules['my_module'])
from my_module import my_function

另一个小问题:如果你使用了import some_module as sm语法,那么你必须用它的别名名称(在这个例子中是sm)重新加载模块:

>>> import some_module as sm
...
>>> import importlib
>>> importlib.reload(some_module) # raises "NameError: name 'some_module' is not defined"
>>> importlib.reload(sm) # works
import sys


del sys.modules['module_name']
import module_name