在交互时重新导入模块

Reimport a module while interactive

提问人:Stefano Borini 提问时间:8/10/2009 最后编辑:Mateen UlhaqStefano Borini 更新时间:7/15/2022 访问量:306608

问:

如何重新导入模块?我想在更改模块的 .py 文件后重新导入模块。

评论

4赞 Walter 5/18/2017
如何卸载(重新加载)Python 模块的可能副本?
0赞 LF00 6/10/2017
重新导入 python 模块

答:

575赞 Benjamin Wohlwend 8/10/2009 #1

对于 Python 3.4+

import importlib
importlib.reload(nameOfModule)

对于 Python < 3.4

reload(my.module)

来自 Python 文档

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

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

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

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

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

评论

64赞 Peter Zhu 7/23/2015
如果我使用 .如何重新加载?from filename import *
11赞 Ted 6/6/2018
@PeterZhu对于“from mod import fcn”的情况,模块对象不会添加到命名空间中。因此,您需要显式导入模块,以便稍后可以重新加载它。import foo; from foo import bar; reload(foo)
2赞 yifanwu 7/31/2019
我尝试了重新加载以及自动重新加载魔术,我看到我的代码更改反映在错误消息的堆栈中,但错误本身似乎仍然与过时的代码无关(例如,错误的行与之前完全相同,我已将其更改为注释,并且注释显然不会导致错误)。我的模块作为 Jupyter 扩展加载,有人知道这是否需要不同的解决方法吗?谢谢!
4赞 Noe 1/7/2020
如果您按照以下方式导入函数 “import mod as name”,则需要执行以下操作: 'import importlib importlib.reload(name)'
0赞 EZLearner 5/5/2020
此方法可能不会覆盖其他模块对重新加载的模块的引用。有关此问题的解决方案,请参阅 stackoverflow.com/a/61617169/2642356
354赞 Andrew 1/18/2013 #2

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

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

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

评论

1赞 jeanmi 4/3/2019
@Andrew谢谢!我使用了 %autoreload,这太棒了,我已经创建的对象自动获得了类方法的正确实现,而无需重新创建它们
6赞 Puff 7/12/2019
我有点晚了,但我认为如果您需要重新加载的是模块中的函数或类,这是行不通的:如果我的导入语句是 ,那么 , ,都会给出 NameError。from mymodule import myfuncimportlib.reload(myfunc)importlib.reload(mymodule.myfunc)importlib.reload(mymodule)
1赞 jss367 3/31/2020
@Puff请参阅下面的答案,了解如何重新导入函数
46赞 funky-future 5/28/2014 #3

实际上,在 Python 3 中,该模块被标记为 DEPRECATED。好吧,至少 3.4 是这样。imp

相反,应使用模块中的函数:reloadimportlib

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

但请注意,该库在最后两个次要版本中进行了一些 API 更改。

1赞 skasch 3/24/2020 #4

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

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

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

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

不过,上一个答案中提到的警告仍然有效。值得注意的是,修改不属于公共 API 的子模块(如变量所述)不会受到使用此函数重新加载的影响。同样,删除子模块的元素也不会反映在重新加载中。__all__

42赞 jss367 3/31/2020 #5

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

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

评论

1赞 taranaki 8/21/2021
我一直在调试一个模块中包含的辅助函数,该模块还导入了 C/Python API,因此只能通过重新启动内核来重新加载。这让事情变得更快了!
15赞 András Aszódi 7/23/2020 #6

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

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

评论

1赞 Quelklef 4/8/2021
请注意,这不是一个特殊的规则,而是 Python 模块是一流的结果。该语句只是分配给一个模块对象。然后,该函数接受此对象。该函数不关心(或知道)名称。import <module> as <name><name>reload()reload()
1赞 András Aszódi 4/8/2021
@Quelklef 好点子,谢谢你的评论。
-1赞 Aldrin 3/12/2021 #7
import sys

del sys.modules['module_name']
import module_name

评论

2赞 Reznik 3/12/2021
请添加一些关于代码的解释,它将提供更多信息和帮助:)
0赞 hekimgil 5/31/2022
解释如下:如果之前加载/导入了该模块,则该模块将添加到 sys.modules 列表中导入的模块列表中,并忽略随后的导入命令。通过从 sys.modules 列表中删除该模块,下次使用 import cammand 时,将重新加载该模块,并将模块名称重新添加到 sys.modules 列表中。