在交互模式下重新导入一个模块。
在Python 3中,模块imp
被标记为DEPRECATED(不推荐使用)。至少在3.4版本中是这样的。
相反,应该使用importlib
模块中的reload
函数:
https://docs.python.org/3/library/importlib.html#importlib.reload
但要注意,这个库在最近的两个次要版本中有一些API变化。
问题的原因是在Python 3中,模块imp
被标记为DEPRECATED,不推荐使用。因此,使用imp
模块重新导入一个模块在交互式环境中会出现问题。
解决方法是使用importlib
模块中的reload
函数来重新导入模块。reload
函数的用法如下:
import importlib importlib.reload(module_name)
其中module_name
是要重新导入的模块名。
需要注意的是,importlib
模块的API在最近的两个次要版本中发生了一些变化。因此,如果使用的是不同的Python 3版本,可能需要查看相应版本的文档来确保代码的正确性。
更多关于importlib
模块的信息可以在官方文档中找到:
在交互模式下重新导入一个模块的问题,主要原因是在修改模块源文件后,想要在不离开Python解释器的情况下尝试新版本。
对于Python 3.4及以上版本,可以使用importlib模块的reload方法进行重新导入,具体代码如下:
import importlib importlib.reload(nameOfModule)
对于Python 3.4以下版本,可以直接使用reload函数进行重新导入,具体代码如下:
reload(my.module)
然而,使用这种方法需要注意以下几点:
1. 当重新导入一个模块时,该模块的字典(包含模块的全局变量)会被保留。如果重新定义了变量名,新的定义将覆盖旧的定义。但是,如果新版本的模块没有定义旧版本的某个变量名,旧的定义不会被移除。
2. 如果一个模块使用`from ... import ...`语句从另一个模块导入对象,在重新导入另一个模块时,并不会重新定义从中导入的对象。解决这个问题的一种方法是重新执行`from`语句,另一种方法是使用`import`和限定的名称(`module.*name*`)。
3. 如果一个模块实例化了一个类的实例,重新加载定义该类的模块不会影响实例的方法定义。同样,对于派生类也是如此。
如果使用`from filename import *`方式导入模块,如何重新加载呢?对于这种情况,模块对象不会添加到命名空间中。所以需要显式地导入模块,以便后续重新加载。例如:
import foo from foo import bar reload(foo)
有人尝试了重新加载和自动重新加载的魔术方法,发现在错误消息的堆栈中看到了代码的更改,但错误本身似乎仍然与旧代码相关。这可能是因为模块以Jupyter扩展的形式加载进来的,可能需要不同的解决方法。
如果使用类似`import mod as name`的方式导入函数,重新加载的方法如下:
import importlib importlib.reload(name)
这种方法可能不会覆盖其他模块对重新加载模块的引用。可以参考相关解决方案。
对于类似`from pylibdmtx.pylibdmtx import decode`的情况,可以使用以下代码进行重新加载:
import importlib import pylibdmtx from pylibdmtx.pylibdmtx import decode importlib.reload(pylibdmtx.pylibdmtx)
有人认为`importlib.reload(nameOfModule)`这种写法容易引起歧义。实际上,`reload()`接受的是一个模块对象,而不是字符串。所以应该使用`importlib.reload(foo)`而不是`importlib.reload('foo')`。或者可以使用`importlib.reload(myModule)`来减少歧义。
如果从自己的模块中导入,比如`from folder.sub_folder.functions import *`,可以参考以上方法进行重新加载。
在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
感谢!我使用了%autoreload,它太棒了,我的已经创建的对象自动获得了修正后的类方法的实现,而无需重新创建它们。
我可能有点晚了,但是我认为如果你需要重新加载模块中的函数或类,这种方法不起作用:如果我的导入语句是from mymodule import myfunc
,那么importlib.reload(myfunc)
,importlib.reload(mymodule.myfunc)
,importlib.reload(mymodule)
都会报错NameError。
请参考下面的答案了解如何重新导入一个函数。