如何在Python解释器中重新导入更新的包?
我经常在Python解释器中testing我的模块,当我看到一个错误,我很快更新.py文件。 但是,我怎样才能使其反映在口译员? 所以,我一直退出并重新进入口译员,因为重新导入文件不适合我。
“重新加载不再是Python 3中的函数。使用imp.reload()而不是”从注释中复制“
使用reload
内置函数:
https://docs.python.org/2/library/functions.html#reload
当
reload(module)
执行时:
- Python模块的代码被重新编译,模块级代码被重新执行,定义了一组绑定到模块字典中名称的新对象。 扩展模块的init函数不是第二次调用。
- 与Python中的所有其他对象一样,旧对象只在引用计数降到零后才被回收。
- 模块名称空间中的名称将更新为指向任何新的或更改的对象。
- 对旧对象的其他引用(例如模块外部的名称)不会反弹到引用新对象,并且必须在每个需要的位置发生更新。
例:
# Make a simple function that prints "version 1" shell1$ echo 'def x(): print "version 1"' > mymodule.py # Run the module shell2$ python >>> import mymodule >>> mymodule.x() version 1 # Change mymodule to print "version 2" (without exiting the python REPL) shell2$ echo 'def x(): print "version 2"' > mymodule.py # Back in that same python session >>> reload(mymodule) <module 'mymodule' from 'mymodule.pyc'> >>> mymodule.x() version 2
以上关于reload()或imp.reload()的所有答案都被弃用了。
reload()不再是python 3中的内build函数,imp.reload()被标记为不赞成使用(请参阅help(imp))。
最好使用importlib.reload()
来代替。
所以,我一直退出并重新进入口译员,因为重新导入文件不适合我。
是的,只是说再次import
给你从sys.modules
模块的现有副本。
你可以说reload(module)
来更新sys.modules
并获得该单个模块的新副本,但是如果任何其他模块具有对原始模块或来自原始模块的任何对象的引用,则它们将保留其旧引用和令人困惑的事情将会发生。
所以如果你有一个模块a
,这取决于模块b
和b
变化,你必须'重新加载b'然后'重新加载'。 如果你有两个相互依赖的模块,当这些模块是同一个软件包的一部分时,这是非常常见的,你不能重新加载它们:如果你重新加载pa
它会得到一个旧的pb
的引用,反之亦然。 唯一的方法就是在再次导入之前,从sys.modules
删除它们的项目,立刻卸载它们。 这是狡猾的,有一些实际的陷阱做与模块条目None作为失败相对导入标记。
如果你有一个模块将对象的引用传递给系统模块,例如注册一个编解码器,或者添加一个警告处理程序, 您不能重新加载系统模块而不会混淆其余的Python环境。
总之:除了一个独立的脚本加载的一个自包含模块的最简单的情况外, reload()
是非常棘手的, 如果如你所暗示的那样,你正在使用一个“包裹”,那么你最好继续循环翻译。
在Python 3中,行为发生变化。
>>> import my_stuff
…用my_stuff做些什么,然后再做:
>>>> import imp >>>> imp.reload(my_stuff)
你得到一个全新的,重新加载my_stuff。
不pipe你导入一个模块多less次,你都会从sys.modules
得到同样的模块副本 – 在第一次import mymodule
我正在回答这个问题,因为上面的每一个答案都有一些答案,所以我试图用一个答案来总结一下。
使用内置函数 :
对于Python 2.x – 使用内置的reload(mymodule)
函数。
对于Python 3.x – 使用imp.reload(mymodule)
。
对于Python 3.4 – 在Python 3.4 imp
已被弃用,有利于importlib
ie importlib.reload(mymodule)
几个警告 :
- 重新加载内置或dynamic加载的模块通常不是很有用。 不推荐重新加载
sys
,__main__
,builtins
和其他关键模块。 - 在很多情况下,扩展模块并不是被devise成多次初始化,并且在重新加载时可能会以任意方式失败。 如果一个模块使用
from
…import
…从另一个模块中导入对象,那么为其他模块调用reload()
并不会重新定义从其导入的对象 – 一种方法是重新执行from
语句,另一个是使用import
和限定名称(module.name)来代替。 - 如果一个模块实例化一个类的实例,重新加载定义该类的模块不会影响实例的方法定义 – 它们继续使用旧的类定义。 派生类也是如此。
外部软件包 :
重新导入 – 重新导入目前支持Python 2.4到2.7。
xreload – 这是通过在临时命名空间中执行模块,然后修补类,方法和函数来实现的。 这避免了需要修补实例。 新对象被复制到目标名称空间中。
livecoding – 代码重新加载允许正在运行的应用程序改变它的行为以响应它使用的Python脚本的改变。 当库检测到Python脚本已被修改时,它将重新加载该脚本,并将其以前用于新加载的版本的对象replace掉。 作为一种工具,它允许程序员避免中断他们的工作stream程并相应地失去焦点。 它使他们能够保持stream动状态。 以前他们可能需要重新启动应用程序才能使更改的代码生效,这些更改可以立即应用。
基本上重新加载,如在allyourcode的asnwer。 但是它不会改变已经实例化的对象或引用函数的代码底层。 从他的回答扩展:
#Make a simple function that prints "version 1" shell1$ echo 'def x(): print "version 1"' > mymodule.py # Run the module shell2$ python >>> import mymodule >>> mymodule.x() version 1 >>> x = mymodule.x >>> x() version 1 >>> x is mymodule.x True # Change mymodule to print "version 2" (without exiting the python REPL) shell2$ echo 'def x(): print "version 2"' > mymodule.py # Back in that same python session >>> reload(mymodule) <module 'mymodule' from 'mymodule.pyc'> >>> mymodule.x() version 2 >>> x() version 1 >>> x is mymodule.x False
简短的回答:
尝试使用重新导入:一个全function的Python重新加载 。
较长的答案:
看起来这个问题是在重新发布之前被问及/回答的,它自称是“Python的全function重新加载”:
该模块旨在成为Python重载function的全function替代品。 它的目标是使重载适用于更长时间运行的应用程序所使用的Python插件和扩展。
重新导入目前支持Python 2.4到2.6。
就其性质而言,这不是一个完全可以解决的问题。 这个模块的目标是让最常见的更新工作。 它还允许个别模块和包装协助过程。 有关发生的更详细的描述在概述页面上。
注意:尽pipereimport
显式支持Python 2.4到2.6,但我一直在2.7上试用它,它似乎工作得很好。
不知道这是否所有预期的事情,但你可以这样做:
>>> del mymodule >>> import mymodule
在这里看到一个很好的解释你的依赖模块将不会被重新加载,并可以有以下效果:
http://pyunit.sourceforge.net/notes/reloading.html
pyunit解决这个问题的方法是通过覆盖__import__来跟踪相关的模块,然后从sys.modules中删除每个模块并重新导入。 不过,他们可能会重新加载它们。
import sys del sys.modules['module_name']
蜻蜓的答案为我工作(蟒3.4.3)。
import sys del sys.modules['module_name']
这是一个较低级别的解决scheme:
exec(open("MyClass.py").read(), globals())