def reload_module(full_module_name):
"""
Assuming the folder `full_module_name` is a folder inside some
folder on the python sys.path, for example, sys.path as `C:/`, and
you are inside the folder `C:/Path With Spaces` on the file
`C:/Path With Spaces/main.py` and want to re-import some files on
the folder `C:/Path With Spaces/tests`
@param full_module_name the relative full path to the module file
you want to reload from a folder on the
python `sys.path`
"""
import imp
import sys
import importlib
if full_module_name in sys.modules:
module_object = sys.modules[full_module_name]
module_object = imp.reload( module_object )
else:
importlib.import_module( full_module_name )
def run_tests():
print( "\n\n" )
reload_module( "Path With Spaces.tests.semantic_linefeed_unit_tests" )
reload_module( "Path With Spaces.tests.semantic_linefeed_manual_tests" )
from .tests import semantic_linefeed_unit_tests
from .tests import semantic_linefeed_manual_tests
semantic_linefeed_unit_tests.run_unit_tests()
semantic_linefeed_manual_tests.run_manual_tests()
if __name__ == "__main__":
run_tests()
sys.path.append('D:\...\My Pythons')
if 'Class_VerticesEdges' in sys.modules:
del sys.modules['Class_VerticesEdges']
print 'old module Class_VerticesEdges deleted'
from Class_VerticesEdges import *
reload(sys.modules['Class_VerticesEdges'])
reload(module) ,但只有当's completely stand-alone. If anything else has a reference to the module (or any object belonging to the module), then you' ll因旧代码挂起而导致的细微且好奇的错误超出预期时, isinstance 之类的东西才能在同一代码的不同版本中运行 .
def importOrReload(module_name, *names):
import sys
if module_name in sys.modules:
reload(sys.modules[module_name])
else:
__import__(module_name, fromlist=names)
for name in names:
globals()[name] = getattr(sys.modules[module_name], name)
# use instead of: from dfly_parser import parseMessages
importOrReload("dfly_parser", "parseMessages")
%autoreload
Reload all modules (except those excluded by %aimport) automatically now.
%autoreload 0
Disable automatic reloading.
%autoreload 1
Reload all modules imported with %aimport every time before executing the Python code typed.
%autoreload 2
Reload all modules (except those excluded by %aimport) every time before
executing the Python code typed.
18 回答
我在Sublime Text中重新加载某些东西时遇到了很多麻烦,但最后我可以编写这个实用程序来重新加载Sublime Text上的模块,基于代码
sublime_plugin.py
用于重新加载模块 .下面接受您从名称中带空格的路径重新加载模块,然后在重新加载后,您可以像往常一样导入 .
如果你第一次运行,这应该加载模块,但如果以后你可以再次使用方法/函数
run_tests()
它将重新加载测试文件 . 使用Sublime Text(Python 3.3.6
)会发生很多事情,因为它的解释器永远不会关闭(除非你重新启动Sublime Text,即Python3.3
解释器) .对于Abaqus来说,它就是它的工作方式 . 想象一下你的文件是Class_VerticesEdges.py
对于Python 2,使用内置函数reload():
对于Python 2和3.2-3.3,请使用reload from module imp:
但
imp
is deprecated自版本3.4 in favor of importlib,所以使用:要么
另一种方法是在函数中导入模块 . 这样,当函数完成时,模块会收集垃圾 .
这是重新加载模块的现代方法:
只需键入
reload(MODULE_NAME)
,将MODULE_NAME
替换为要重新加载的模块的名称 .例如,
reload(math)
将重新加载数学函数 .其他选择 . 看到Python默认
importlib.reload
将重新导入作为参数传递的库 . 它 won't 重新加载你的lib导入的库 . 如果您更改了大量文件并且要导入一些复杂的程序包,则必须执行 deep reload .如果安装了IPython或Jupyter,则可以使用函数深度重新加载所有库:
如果您没有Jupyter,请在shell中使用此命令安装它:
您可以使用reload builtin函数在已导入模块时重新加载模块:
在Python 3中,
reload
被移动到imp模块 . 在3.4中,imp
被弃用,而importlib,reload被添加到后者 . 当定位3或更高版本时,要么在调用reload
时引用相应的模块,要么导入它 .我认为这就是你想要的 . 像Django的开发服务器这样的Web服务器使用它,这样您就可以看到代码更改的效果,而无需重新启动服务器进程本身 .
引用文档:
如您在问题中所述,如果
Foo
类位于foo
模块中,则必须重建Foo
对象 .reload(module)
,但只有当's completely stand-alone. If anything else has a reference to the module (or any object belonging to the module), then you' ll因旧代码挂起而导致的细微且好奇的错误超出预期时,isinstance
之类的东西才能在同一代码的不同版本中运行 .如果您有单向依赖项,则还必须重新加载依赖于重新加载的模块的所有模块,以去除对旧代码的所有引用 . 然后递归地重新加载依赖于重新加载的模块的模块 .
如果您具有循环依赖关系(例如,在处理重新加载包时非常常见),则必须一次性卸载组中的所有模块 . 您无法使用
reload()
执行此操作,因为它将在刷新依赖项之前重新导入每个模块,从而允许旧引用进入新模块 .在这种情况下,唯一的方法是破解
sys.modules
,这是一种不受支持的 . 您必须通过并删除下次导入时要重新加载的每个sys.modules
条目,并删除值为None
的条目,以处理与缓存失败的相对导入有关的实现问题 . 它将引用留在其代码库之外,它是可行的 .最好重启服务器 . :-)
接受的答案不处理来自X导入Y的情况 . 此代码也处理它和标准导入案例:
在重新加载的情况下,我们将顶级名称重新分配给新重新加载的模块中存储的值,这些值会更新它们 .
Enthought Traits有一个适用于此的模块 . https://traits.readthedocs.org/en/4.3.0/_modules/traits/util/refresh.html
它将重新加载已更改的任何模块,并更新正在使用它的其他模块和实例化对象 . 它在大多数情况下都不能用
__very_private__
方法工作,并且可以阻止类继承,但它在编写PyQt guis时不必重新启动宿主应用程序,或者在Maya或Nuke等程序中运行的东西,这节省了我的时间 . . 它还没有令人难以置信的帮助 .Enthought的软件包在它们改变的那一刻不会重新加载文件 - 你必须明确地调用它 - 但如果你真的需要它,这应该不是那么难以实现
那些使用python 3并从importlib重新加载的人 .
如果你有类似的问题似乎模块没有重新加载...这是因为它需要一些时间来重新编译pyc(最多60秒) . 我写这个提示只是你知道你是否遇到过这种问题 .
以下代码允许您兼容Python 2/3:
您可以在两个版本中将它用作
reload()
,这使事情变得更简单 .在Python 3.0-3.3中,您将使用:imp.reload(module)
BDFL有answered这个问题 .
但是,imp was deprecated in 3.4, in favour of importlib(谢谢@Stefan!) .
因此,我认为你现在使用importlib.reload(module),虽然我不确定 .
对于那些想要卸载所有模块的人(当在Emacs下的Python解释器中运行时):
更多信息请参见Reloading Python modules .
如果您不在服务器中,但正在开发并需要经常重新加载模块,这里有一个很好的提示 .
首先,确保您使用Jupyter Notebook项目中出色的IPython shell . 安装Jupyter后,您可以使用
ipython
或jupyter console
,甚至更好的jupyter qtconsole
启动它,这将为您提供一个漂亮的彩色控制台,在任何操作系统中都可以完成代码 .现在在shell中输入:
现在, every time 您运行脚本,您的模块将被重新加载 .
除了
2
之外,还有其他options of the autoreload magic:如果模块不是纯Python,则删除模块尤其困难 .
以下是一些信息:How do I really delete an imported module?
2018年2月1日
module
foo
必须提前成功导入 .from importlib import reload
,reload(foo)
31.5. importlib — The implementation of import — Python 3.6.4 documentation