如何在Python Interpreter中重新导入更新的包?

时间:2009-03-26 01:19:42

标签: python

我经常在Python Interpreter中测试我的模块,当我看到错误时,我会快速更新.py文件。但是如何让它反映在口译员身上呢?所以,我一直在退出并重新进入口译员,因为重新导入该文件对我来说不起作用。

11 个答案:

答案 0 :(得分:296)

Python3更新 :(引自already-answered answer,因为上次编辑/评论建议使用弃用方法)

  

在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)
<module 'mymodule' from 'mymodule.pyc'>
>>> mymodule.x()
version 2

答案 1 :(得分:197)

以上关于reload()imp.reload()的所有答案均已弃用。

reload()不再是python 3中的内置函数,imp.reload()被标记为已弃用(请参阅help(imp))。

最好使用importlib.reload()

答案 2 :(得分:36)

  

所以,到目前为止,我一直在退出并重新进入口译员,因为重新导入该文件对我来说不起作用。

是的,只需再次说import就可以从sys.modules为您提供模块的现有副本。

您可以说reload(module)更新sys.modules并获取该单个模块的新副本,但是如果任何其他模块引用了原始模块或原始模块中的任何对象,他们将保留旧的参考资料,并且会发生非常令人困惑的事情。

因此,如果您有一个模块a(取决于模块bb更改),则必须“重新加载b”,然后“重新加载”。如果你有两个相互依赖的模块,当这些模块属于同一个软件包时非常常见,你就不能重新加载它们:如果你重新加载p.a它会得到一个参考旧的p.b,反之亦然。唯一的方法是在再次导入之前,通过从sys.modules删除项目来同时卸载它们。这是icky并且有一些实际的陷阱与模块条目为None作为失败的相对导入标记。

如果你有一个模块将对象的引用传递给系统模块 - 例如它注册一个编解码器,或者添加一个警告处理程序 - 你就被卡住了;如果不混淆Python环境的其余部分,就无法重新加载系统模块。

总结:除了最简单的一个自包含模块由一个独立脚本加载的情况之外,reload()非常难以正确;如果,正如你暗示的那样,你使用的是“套餐”,那么继续循环翻译可能会更好。

答案 3 :(得分:25)

在Python 3中,行为发生了变化。

>>> import my_stuff

...用my_stuff做一些事情,然后再做一些事情:

>>>> import imp
>>>> imp.reload(my_stuff)

你得到一个全新的,重新加载my_stuff。

答案 4 :(得分:17)

无论您导入模块多少次,您都会从import mymodule获取该模块的相同副本 - 该模块首先加载imp

我正在回答这个问题,因为上述/上一个答案都有一点答案,所以我试图在一个答案中总结一下。

使用内置功能

对于 Python 2.x - 使用内置的reload(mymodule)函数。

对于 Python 3.x - 使用imp.reload(mymodule)

对于 Python 3.4 - 在Python 3.4 importlib中已弃用sys,即importlib.reload(mymodule)

很少有警告

  • 重新加载内置或动态通常不是很有用 加载模块。重新加载__main__frombuiltins和其他密钥 不建议使用模块。
  • 在许多情况下,扩展模块不是 设计为不止一次初始化,并且可能任意失败 重新加载的方式。如果模块从另一个模块导入对象 使用import ... reload() ...,为其他模块调用from 不重新定义从它导入的对象 - 一种方法是 重新执行import语句,另一个是使用<a>并且合格 而是名称(module.name)。
  • 如果模块实例化a的实例 class,重新加载定义类的模块不会影响 实例的方法定义 - 他们继续使用 旧班定义。派生类也是如此。

外部套餐

reimport - Reimport目前支持Python 2.4到2.7。

xreload - 这可以通过在临时命名空间中执行模块来实现 修补类,方法和功能到位。这避免了 需要修补实例。新对象将复制到目标中 命名空间。

livecoding - 代码重新加载允许正在运行的应用程序更改其行为以响应其使用的Python脚本中的更改。当库检测到Python脚本已被修改时,它会重新加载该脚本并替换之前可用于新重新加载版本的对象。作为一种工具,它允许程序员避免中断他们的工作流程并相应地失去焦点。它使它们能够保持流动状态。以前他们可能需要重新启动应用程序以使更改的代码生效,这些更改可以立即应用。

答案 5 :(得分:10)

基本上reload和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

答案 6 :(得分:10)

简短回答:

尝试使用reimport: a full featured reload for Python

更长的答案:

reimport发布之前看起来这个问题已经被提出/回答了,它将自己称为“Python的全功能重装”:

  

该模块旨在成为Python重载功能的全功能替代品。它的目标是进行重新加载,适用于运行时间较长的应用程序使用的Python插件和扩展。

     

Reimport目前支持Python 2.4到2.6。

     

就其本质而言,这不是一个完全可以解决的问题。该模块的目标是使最常见的各种更新运行良好。它还允许单个模块和包装协助该过程。有关更改的详细说明,请参见概述页面。

注意:尽管reimport明确支持Python 2.4到2.6,但我一直在2.7上尝试它,它似乎工作正常。

答案 7 :(得分:4)

不确定这是否适合所有预期的事情,但你可以这样做:

>>> del mymodule
>>> import mymodule

答案 8 :(得分:3)

请在此处查看有关如何重新加载相关模块的详细说明以及可能产生的效果:

http://pyunit.sourceforge.net/notes/reloading.html

pyunit解决它的方法是通过覆盖__import__来跟踪依赖模块,然后从sys.modules中删除它们并重新导入。不过,他们可能只是重装了它们。

答案 9 :(得分:2)

import sys
del sys.modules['module_name']

答案 10 :(得分:-1)

蜻蜓的回答对我有用(python 3.4.3)。

import sys
del sys.modules['module_name']

这是一个较低级别的解决方案:

exec(open("MyClass.py").read(), globals())