在交互式时在python中重新导入模块

时间:2009-08-10 11:24:17

标签: python

我知道可以做到,但我永远不会记得如何。

如何在python中重新导入模块? 方案如下:我以交互方式导入模块并修改它,但后来我遇到了错误。我修复.py文件中的错误然后我想重新导入修复模块而不退出python。我该怎么办?

7 个答案:

答案 0 :(得分:281)

这应该有效:

reload(my.module)

来自Python docs

  

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

如果运行Python 3.4及更高版本,请执行import importlib,然后执行importlib.reload(nameOfModule)

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

  • 重新加载模块时,会保留其字典(包含模块的全局变量)。名称的重新定义将覆盖旧的定义,因此这通常不是问题。如果新版本的模块未定义旧版本定义的名称,则旧定义仍然存在。

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

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

答案 1 :(得分:227)

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

如果您使用的是python 3.4+,则应使用reload库中的importlib代替:

import importlib
importlib.reload(some_module)

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

import imp  
imp.reload(module)  

代替。见http://docs.python.org/3.0/library/imp.html#imp.reload

如果您使用ipython,请务必考虑使用autoreload扩展程序:

%load_ext autoreload
%autoreload 2

答案 2 :(得分:44)

实际上,在Python 3中,模块imp被标记为DEPRECATED。好吧,至少对于3.4来说这是真的。

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

https://docs.python.org/3/library/importlib.html#importlib.reload

但请注意,此库在最后两个次要版本中有一些API更改。

答案 3 :(得分:12)

如果要从模块导入特定的函数或类,可以执行以下操作:

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

答案 4 :(得分:3)

另一个要点:如果使用import some_module as sm语法,则必须使用其别名 (在此示例中为sm)重新加载模块:< / p>

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

答案 5 :(得分:0)

尽管提供的答案确实适用于特定模块,但它们不会重新加载子模块,如This answer中所述:

如果一个模块使用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的子模块将不会受到使用此函数进行的重新加载的影响。同样,删除子模块的元素也不会反映在重新加载中。

答案 6 :(得分:-1)

import sys

del sys.modules['module_name']
import module_name