繁体   English   中英

从控制台重新加载 python 模块的正确方法

[英]Proper way to reload a python module from the console

我正在从 python 控制台进行调试,每次进行更改时都想重新加载模块,这样我就不必退出控制台并重新输入它。 我正在做:

>>> from project.model.user import *
>>> reload(user)

但我收到:

>>>NameError: name 'user' is not defined

重新加载整个用户类的正确方法是什么? 有没有更好的方法来做到这一点,也许在调试时自动更新?

谢谢。

正如所问,你能做的最好的是

>>> from project.models.user import *
>>> import project # get module reference for reload
>>> reload(project.models.user) # reload step 1
>>> from project.models.user import * # reload step 2

如果您直接使用用户模块,而不是执行import * (这几乎从来都不是正确的方法),它会更好更干净。 那么它只会是

>>> from project.models import user
>>> reload(user)

这会做你想做的。 但是,它不是很好。 如果你真的需要如此频繁地重新加载模块,我不得不问:为什么?

我的怀疑(由之前人们提出类似问题的经验支持)是您正在测试您的模块。 有很多方法可以测试一个模块,在交互式解释器中手工测试是最糟糕的方法之一。 将您的一个会话保存到一个文件中并使用doctest进行快速修复。 或者,将其写为程序并使用python -i 不过,唯一真正好的解决方案是使用unittest模块。

如果不是这样,希望它会更好,而不是更糟。 reload真的没有什么好用的(其实在3.x中已经去掉了)。 它不能有效地工作——您可能会重新加载一个模块,但会留下以前版本的剩余部分。 它甚至不适用于所有类型的模块——扩展模块在重新加载时无法正确重新加载,有时甚至会严重中断。

在交互式解释器中使用它的上下文并没有留下很多关于您正在做什么以及真正的最佳解决方案的选择。 在它之外,有时人们使用reload()来实现插件等。这充其量是危险的,并且经常可以使用exec (啊,我们发现自己处于邪恶的领域)或隔离的进程以不同的方式完成。

对于python3,重新加载已移至imp 模块。 你可以使用imp.reload() 你可以参考这个帖子

>>> import imp
>>> import project # get module reference for reload
>>> imp.reload(project.models.user) # reload step 1
>>> from project.models.user import * # reload step 2

您不能以有效的方式使用 reload()。

Python 没有提供对先前导入的模块的重新加载或卸载的有效支持; 模块引用使得重新加载模块变得不切实际,因为引用可能存在于程序的许多地方。

Python 3 已完全删除 reload() 功能。

IPython 可以在执行每个新行之前重新加载模块:

%load_ext autoreload
%autoreload 2

其中%autoreload 2每次在执行输入的 Python 代码之前重新加载“所有模块(除了那些被 %aimport 排除的模块)。”

查看文档:

不幸的是,您必须使用:

>>> from project.model import user
>>> reload(user)

我不知道会在交互式提示下自动重新加载模块的东西...任何一个…)

现在,你可以做这样的事情:

from types import ModuleType
import sys
_reload_builtin = reload
def reload(thing):
    if isinstance(thing, ModuleType):
        _reload_builtin(thing)
    elif hasattr(thing, '__module__') and thing.__module__:
        module = sys.modules[thing.__module__]
        _reload_builtin(module)
    else:
        raise TypeError, "reload() argument must be a module or have an __module__"

您也可以尝试twisted.python.rebuild.rebuild

    from test_reload import add_test

其中test_reload是一个模块, add_test是一个函数,如果你改变了函数add_test ,当然你需要重新加载这个函数。 那么你可以这样做:


    import imp
    imp.reload(test_reload)
    from test_reload import add_test

这将刷新函数add_test

所以你需要添加

imp.reload(test_reload)
from test_reload import add_test  --add this line in your code

从 Python 3.4 开始,您可以使用importlib.reload(module)

>>> from importlib import reload
>>> from project.model import user
>>> reload(user)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM