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

ens*_*are 30 python

我正在从python控制台调试,并希望每次进行更改时重新加载模块,所以我不必退出控制台并重新输入它.我正在做:

>>> from project.model.user import *
>>> reload(user)
Run Code Online (Sandbox Code Playgroud)

但我收到:

>>>NameError: name 'user' is not defined
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Dev*_*rre 42

如所问的那样,你能做的最好的就是

>>> 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
Run Code Online (Sandbox Code Playgroud)

如果你直接使用用户模块,而不是做import *(这几乎不是正确的方法),它会更好更清洁.那就是

>>> from project.models import user
>>> reload(user)
Run Code Online (Sandbox Code Playgroud)

这可以做你想要的.但是,它不是很好.如果你真的需要经常重新加载模块,我必须问:为什么?

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

如果那不是它,希望它更好,而不是更糟.实际上并没有很好用reload(事实上​​,它已经在3.x中删除了).它无法有效工作 - 您可能会重新加载模块,但会留下以前版本的剩余部分.它甚至不适用于所有类型的模块 - 扩展模块在重新加载时不会正确地重新加载,或者有时甚至会破坏.

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

  • 你很少会看到我反对单元测试,但肯定会有一些情况,当你进行原型设计时,这将是有价值的.并不是不同意整体情绪,但"最糟糕的方式之一"是非常严厉的价值判断. (12认同)
  • 天真地与medwards。我在python调试器内部使用reload在这里找到了自己的方式。在调试可编辑包时,我希望修改并重新加载模块并调用有问题的例程,而不是每次退出python并从头开始。为什么那不是有效的reload()方法?方案与单元测试无关。 (2认同)

Kri*_*ofe 7

对于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
Run Code Online (Sandbox Code Playgroud)

  • 自 Python 3.4 起,imp 模块已被弃用,取而代之的是 importlib。参考:https://docs.python.org/3/library/imp.html (2认同)

sys*_*out 5

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

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

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


Ant*_*nko 5

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

%load_ext autoreload
%autoreload 2
Run Code Online (Sandbox Code Playgroud)

其中%autoreload 2重新加载“所有模块(除了那些由%aimport除外)执行Python代码键入之前每时间”。

查看文档: