重新加载模块时出现NameError:未定义名称'reload'。

180
我正在尝试在Python 3中重新加载一个已经导入的模块。我知道只需要导入一次,再次执行import命令不会产生任何作用。
执行reload(foo)会产生此错误:
Traceback (most recent call last):
    File "(stdin)", line 1, in (module)
    ...
NameError: name 'reload' is not defined

这个错误的意思是什么?

7个回答

251

reload 是 Python 2 中的内置函数,但在 Python 3 中已被删除,因此您看到的错误是预期的。

如果您确实需要在 Python 3 中重新加载一个模块,您应该使用以下方法之一:


42
这个回答让人觉得在Python 3中重新加载模块是不好的。这背后的思考是什么? - ABM
13
重新加载始终是一个问题。重新加载会更新模块变量,但不会删除旧变量,因此如果您重命名某个变量,旧名称仍将存在。如果更改类定义,则现有对象仍将具有旧类型。最后,某些模块在导入时运行的代码不是设计为可以运行两次的。因此最好避免重新加载,但有时非常方便。 - Evan
14
我认为这个问题通常是有问题的,但并非总是如此。确实,我认为在脚本中写入reload的有效用例非常罕见,那些使用这种黑暗技术的人不太可能会阅读这条评论。然而,如果你正在开发一个模块并使用IPython控制台进行交互测试,那么在这种工作流中使用reload会很方便。就像@Evan所说,要注意导入时副作用。总的来说,我建议避免重新加载别人的模块。在设计时重新加载自己的模块是有意义的。 - Tim D
7
我使用 Jupyter 笔记本进行工作,为了使事情井井有条,我将应该需要最少修改的工作放入可导入的软件包中。然而,这些内容有时需要修订,重新加载是绝对正确的做法,因为我的笔记本内核正在内存中保留需要一整天才能计算出来的计算结果。 - Him
重新加载对于具有耗时调用(例如数据库函数)的库的活跃开发至关重要。然而,重新加载模块时可能会遇到的主要问题之一是带有装饰器的函数往往无法正确重新加载,请参见此处 - Alexander McFarlane
该方法可能无法覆盖其他模块对重新加载的模块的引用。请参阅 https://dev59.com/knRC5IYBdhLWcg3wAcXU#61617169 以获取解决方案。 - EZLearner

98

对于 Python3.4 及以上版本:

import importlib
importlib.reload(module)

对于Python3.3及以下版本:

import imp
imp.reload(module)

对于Python2.x:

使用内置的reload()函数。

reload(module)

对我来说,如果我运行例如 imp.reload(plt)imp.reload(matplotlib.pyplot) 则上述两者都有效,但是如果我运行 imp.reload(script) 则无效。plt 被设置为 import matplotlib.pyplot as plt。你知道为什么如果我尝试重新加载我自己编写并先前导入的脚本时它不起作用吗?会出现以下错误 ModuleNotFoundError: spec not found for the module 'script' - Herwini

49
import imp
imp.reload(script4)

8
自Python 3.4起已被弃用 - 请改用importlib - Mark Amery

41

在之前的答案基础上进一步解释,如果您想要一个适用于Python 2和3版本的单一解决方案,您可以使用以下内容:

try:
    reload  # Python 2.7
except NameError:
    try:
        from importlib import reload  # Python 3.4+
    except ImportError:
        from imp import reload  # Python 3.0 - 3.3

13

我建议使用以下代码片段,因为它适用于所有Python版本(需要six):

from six.moves import reload_module
reload_module(module)

这应该是最好的答案。 - Ke Lu
这应该是最好的答案。 - undefined

5

为了实现Python2和Python3的兼容性,您可以使用以下代码:

# Python 2 and 3
from imp import reload
reload(mymodule)

1
这在Python 3.7(以及更早版本)中有效,但正如@Alex Martelli在下面所写的那样,已被弃用。使用Alleo的答案“from six.moves import reload_module”。 - Charles Plager

4
如果您不想使用外部库,则可以按照以下方式重新创建Python 2中的reload方法以在Python 3中使用。将其放置于模块顶部(假定Python 3.4+)。
import sys
if(sys.version_info.major>=3):
    def reload(MODULE):        
        import importlib
        importlib.reload(MODULE)

顺便提一下,如果你使用Python文件作为配置文件并希望避免应用程序重新启动,则非常需要重新加载(reload)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接