【问题标题】:Reload in Python interpreter在 Python 解释器中重新加载
【发布时间】:2012-05-11 04:47:50
【问题描述】:
$ python
>>> import myapp
>>> reload(myapp)
<module 'myapp' from 'myapp.pyc'>
>>>

ctrl+D

$ python
>>> from myapp import *
>>> reload(myapp)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'myapp' is not defined

为什么会有不同的行为?使用from myapp import *时如何重新加载?

【问题讨论】:

  • 我之所以使用 reload() 是因为我更改了模块的源代码并测试它以及我使用 from myapp import 的原因是因为它节省了我的打字时间。
  • reload 要谨慎使用很多。它在许多方面表现出意外,其中最糟糕的是类存在于 VM 内的许多版本中,这取决于您是否有重新加载类的旧实例。出于这个原因,reload 已从 Python 3 中删除。通常,设置一个小脚本来设置您需要的所有模块,然后使用import code; code.interact(local=locals()) 将其放入 shell 会容易得多。 Python 解释器启动得非常快,所以这通常比在 readline 历史记录中搜索 reload 更快。
  • @NiklasB。谢谢你的建议,但如果没有一些例子,我无法想象。如果可能并且您有时间写更多关于它的信息,请在答案中举一些例子。或者,如果您不反对,我可以根据您的评论创建一个新问题。
  • 我的意思是pastie.org/3844991。您可以使用该脚本从头开始重新加载整个 shell,而不是打开 shell 并尝试重新加载内容(无法正常工作)。这还具有强制您显式设置要测试的上下文的优势,因此您可以重现您所做的一切,并可以选择稍后轻松地将其转换为单元测试。
  • @NiklasB 非常感谢,好主意。

标签: python interpreter reload


【解决方案1】:

来自http://docs.python.org/library/functions.html#reload

如果一个模块使用 from ... import 从另一个模块导入对象 ...,为其他模块调用 reload() 不会重新定义 从它导入的对象——解决这个问题的一种方法是重新执行 from 语句,另一个是使用导入和限定名 (模块。名称)。

所以,你应该这样做:

from myapp import *
....
import myapp
reload(myapp)
from myapp import *

【讨论】:

    【解决方案2】:

    使用from myapp import *时如何重新加载?

    你不能。这就是为什么使用from X import * 是个坏主意的原因之一。

    【讨论】:

    • 调试的时候也不错。它可以节省打字。
    【解决方案3】:

    使用from myapp import *,您没有在变量名中引用您的模块,因此您不能使用变量名来引用该模块。

    当然,没有什么可以阻止您再次导入它以获取对您可以使用的名称的模块的引用。由于已经导入过一次,实际上不会再次导入:

    import myapp
    reload(myapp)
    

    您也可以直接从sys.modules获取参考。

    import sys
    reload(sys.modules["myapp]")
    

    【讨论】:

    • 导入和重新加载模块实际上不会重新绑定任何与from foo import * 绑定的名称。这可能会或很多不会使重新加载无用。
    • 我之所以使用 reload() 是因为我更改了模块的源代码并测试它以及我使用 from myapp import 的原因是因为它节省了我的打字时间。
    【解决方案4】:

    为了澄清 Wooble 的评论,使用“from foo import *”将 foo 中的所有内容带入当前命名空间。这可能会导致名称冲突(您无意中为已使用的名称分配了一个新值),并且还可能使您更难分辨某物的来源。虽然有一些库经常以这种方式使用,但它通常会导致比其价值更多的问题。

    此外,由于它已被带入当前命名空间,因此不能简单地重新加载。通常最好将其保存在单独的命名空间中(可能使用更短的便利别名,例如 m)。这允许您重新加载(这对于测试很有用,但在测试之外很少是一个好主意)并有助于保持命名空间的纯净。

    【讨论】:

      猜你喜欢
      • 2012-09-17
      • 2011-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      • 1970-01-01
      相关资源
      最近更新 更多