您只能^{}一个模块:The argument must be a module object, so it must have been successfully imported before.

在您的例子中,您没有对模块对象的任何引用。您将不得不import它,即使您不想将它用于其他任何事情,只是为了以后调用reload。

另外,在reload之后,您有import的名称:Other references to the old objects (such as names external to the module) are not rebound to refer to the new objects and must be updated in each namespace where they occur if that is desired.

当您执行from foo import bar操作时,bar是“模块外部的名称”,因此您必须显式地重新绑定它。

如果你仔细想想,它的工作方式是这样的。reload无法枚举其定义依赖于以前版本的模块的所有对象来更新它们。即使可以,也可能有无限的循环。如果新版本甚至没有旧版本中的类的定义,会发生什么呢?或者如果类是动态定义的?

换个角度看,from foo import bar与{}非常相似。bar是名称空间中的一个名称,而不是foo的名称空间,因此{}不会触及它;您需要将新的foo.bar复制一次。

解决所有这些问题的简单方法是在reload之后重复所有的from foo import bar行。

对于简单情况:

import video
from video import MLStripper
# ... later
imp.reload(video)
from video import MLStripper

但是,大多数示例都有明显的命名冲突:一旦from video import video,就不能再reload(video)。因此,您需要另一个对video模块对象的引用。

Python为您保留了一个,您可以使用:

^{pr2}$

或者,您也可以使用as子句,或者仅仅使用一个=赋值来给它取任何你想要的名字。在import video as _video

from video import video
# ... later
imp.reload(_video)
from video import video

从你的评论和你编辑的问题来看,你似乎还有更大的问题。让我们用一个简单的非碰撞案例来讨论它。

我相信你确实在做这样的事情:

import video
from video import MLStripper
stripper = MLStripper('foo")
# ... later
imp.reload(video)
from video import MLStripper

第一行将成功地重新加载video模块,第二行将把它的MLStripper类复制到全局变量中,因此您创建的任何新的MLStripper实例都将是新类型。

但这不会影响任何现有的MLStripper实例,比如stripper。

就像MLStripper一样,stripper是“模块外部的名称”之一。但事实上更糟。为了调整它,reload必须弄清楚它的状态,如果新版本的代码从创建时起就生效了。这显然是一个无法解决的问题。

如果您知道要修补的实例,则可以使用与处理类相同的方式有效地处理它们:只需再次创建它们:

imp.reload(video)
from video import MLStripper
stripper = MLStripper('foo")

如果这还不够好,有三种可能是你想要的:Monkeypatch将方法、属性等放入实例及其__class__。

直接修补实例的__class__属性,这样从类继承的任何内容现在都将从新类继承。

在reload之前用pickle序列化实例,然后在之后反序列化。

对于非常简单的情况,这三种方法都有效。对于更复杂的情况,你必须明白你在做什么。

请注意,您可以在一个函数中包装这些内容,但是您必须了解local和global的工作原理(以及import和reload的工作原理),否则您将自己弄糊涂。

更简单的解决方案是只创建“dump all state”和“load all state”函数。然后你可以抛弃一切,退出,重新启动,恢复。Python教程和ipython文档都描述了一些不同的方法来代替使用reload;可能值得回顾一下并重新阅读这些方法。