我经常在Python Interpreter中测试我的模块,当我看到错误时,我会快速更新.py文件.但是如何让它反映在口译员身上呢?所以,我一直在退出并重新进入解释器,因为重新导入文件对我来说不起作用.
Python3的更新:(引用已经回答的答案,因为上次编辑/评论建议使用不推荐的方法)
在Python 3中,
reload
被移动到imp
模块.在3.4中,imp
被弃用赞成importlib
,reload
并被添加到后者中.当定位3或更高版本时,要么在调用时引用相应的模块,要么reload
导入它.
带走:
Python3> = 3.4: importlib.reload(packagename)
Python3 <3.4: imp.reload(packagename)
Python2:继续下面
使用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)>>> mymodule.x() version 2
以上所有答案都已弃用reload()
或imp.reload()
已被弃用.
reload()
不再是python 3中的内置函数,并且imp.reload()
标记为已弃用(请参阅参考资料help(imp)
).
最好使用它importlib.reload()
.
所以,我一直在退出并重新进入解释器,因为重新导入文件对我来说不起作用.
是的,再说import
一遍就会给你现有的模块副本sys.modules
.
您可以说reload(module)
更新sys.modules
并获取该单个模块的新副本,但如果任何其他模块具有对原始模块或原始模块中的任何对象的引用,则它们将保留其旧引用并且将发生非常混乱的事情.
因此,如果你有一个模块a
,它取决于模块b
和b
更改,你必须'重新加载b'然后'重新加载'.如果你有两个相互依赖的模块,当这些模块是同一个软件包的一部分时非常常见,你就不能重新加载它们:如果你重新加载p.a
它会得到一个旧的参考p.b
,副反之亦然.唯一的方法是在再次sys.modules
导入之前,通过删除它们的项目来同时卸载它们.这是icky并且有一些实际的陷阱与模块条目为None作为失败的相对导入标记.
如果你有一个模块将对象的引用传递给系统模块 - 例如它注册一个编解码器,或者添加一个警告处理程序 - 你就被卡住了; 您无法重新加载系统模块而不会混淆其余的Python环境.
总结:除了最简单的一个自包含模块由一个独立脚本加载的情况之外,reload()
要做到正确是非常棘手的.如果,正如你暗示的那样,你使用的是"套餐",那么你可能最好继续循环翻译.
在Python 3中,行为发生了变化.
>>> import my_stuff
...用my_stuff做一些事情,然后再做:
>>>> import imp >>>> imp.reload(my_stuff)
你得到一个全新的,重新加载my_stuff.
无论您导入模块多少次,您都会获得相同的模块副本sys.modules
- 首先加载模块import mymodule
我正在回答这个问题,因为上面/前面的每个答案都有一点答案,所以我试图在一个答案中总结一下.
使用内置功能:
对于Python 2.x - 使用内置reload(mymodule)
函数.
对于Python 3.x - 使用imp.reload(mymodule)
.
对于Python 3.4 - 在Python 3.4中imp
已被弃用,赞成importlib
ieimportlib.reload(mymodule)
几点需要注意:
重新加载内置或动态加载的模块通常不是很有用.重装sys
,__main__
,builtins
不建议和其他关键模块.
在许多情况下,扩展模块不是设计为多次初始化,并且在重新加载时可能以任意方式失败.如果模块使用from
......来从另一个模块导入对象import
,则调用reload()
另一个模块不会重新定义从其导入的对象 - 一种方法是重新执行该from
语句,另一种方法是使用import
和限定名称( module.name)而不是.
如果模块实例化类的实例,则重新加载定义类的模块不会影响实例的方法定义 - 它们继续使用旧的类定义.派生类也是如此.
外包装:
重新导入 - Reimport目前支持Python 2.4到2.7.
xreload - 这是通过在临时命名空间中执行模块,然后修补类,方法和函数来实现的.这避免了修补实例的需要.新对象将复制到目标命名空间中.
实时编码 - 代码重新加载允许正在运行的应用程序更改其行为以响应其使用的Python脚本中的更改.当库检测到Python脚本已被修改时,它会重新加载该脚本并替换之前可用于新重新加载版本的对象.作为一种工具,它允许程序员避免中断他们的工作流程并相应地失去焦点.它使它们能够保持流动状态.以前他们可能需要重新启动应用程序以使更改的代码生效,这些更改可以立即应用.
基本上像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)>>> mymodule.x() version 2 >>> x() version 1 >>> x is mymodule.x False
简短回答:
尝试使用reimport:Python的全功能重装.
更长的回答:
看起来这个问题在重新导入发布之前被提出/回答了,它将自己称为"Python的全功能重装":
该模块旨在成为Python重载功能的全功能替代品.它的目标是进行重新加载,适用于运行时间较长的应用程序使用的Python插件和扩展.
Reimport目前支持Python 2.4到2.6.
就其本质而言,这不是一个完全可解决的问题.该模块的目标是使最常见的各种更新运行良好.它还允许单个模块和包装协助该过程.有关更改的详细说明,请参见概述页面.
注意:虽然reimport
明确支持Python 2.4到2.6,但我一直在2.7上尝试它,它似乎工作得很好.