问题:交互时在python中重新导入模块
我知道可以做到,但是我不记得怎么做。
如何在python中重新导入模块?场景如下:我以交互方式导入模块并对其进行修改,但随后遇到错误。我修复了.py文件中的错误,然后想重新导入固定模块而不退出python。我该怎么做 ?
回答 0
这应该工作:
reload(my.module)
来自Python文档
重新加载先前导入的模块。参数必须是模块对象,因此它必须已经成功导入。如果您已使用外部编辑器编辑了模块源文件,并且想在不离开Python解释器的情况下尝试新版本,则这将非常有用。
如果运行Python 3.4及更高版本,请执行import importlib
,然后执行importlib.reload(nameOfModule)
。
不要忘记使用此方法的注意事项:
重新加载模块时,将保留其字典(包含模块的全局变量)。名称的重新定义将覆盖旧的定义,因此通常这不是问题,但是如果模块的新版本未定义旧版本定义的名称,则不会删除旧定义。
如果一个模块使用导入了另一个模块的对象
from ... import ...
,则调用reload()
另一个模块的操作并未重新定义从该模块导入的对象-解决该问题的一种方法是重新执行该from
语句,另一种方法是使用import
和限定名称(module.*name*
)。如果模块实例化一个类的实例,则重新加载定义该类的模块不会影响实例的方法定义-它们将继续使用旧的类定义。派生类也是如此。
回答 1
在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
实际上,在Python 3中,该模块imp
被标记为DEPRECATED。好吧,至少对于3.4是正确的。
而是应使用模块中的reload
功能importlib
:
https://docs.python.org/3/library/importlib.html#importlib.reload
但是请注意,该库在最后两个次要版本中进行了一些API更改。
回答 3
如果要从模块导入特定的函数或类,可以执行以下操作:
import importlib
import sys
importlib.reload(sys.modules['my_module'])
from my_module import my_function
回答 4
尽管提供的答案确实适用于特定模块,但它们不会重新加载子模块,如本答案所述:
如果一个模块使用导入了另一个模块的对象
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的子模块将不会受到使用此函数进行的重新加载的影响。同样,删除子模块的元素也不会反映在重新加载中。