如何在 Python 解释器中重新导入更新的包?[重复]

2025-04-15 09:19:00
admin
原创
33
摘要:问题描述:我经常在 Python 解释器中测试模块,一旦发现错误,就会快速更新 .py 文件。但是,如何让错误反映到解释器中呢?到目前为止,我一直都是退出解释器再重新进入,因为重新导入文件对我来说不起作用。解决方案 1:Python3 的更新:(引用自已经回答的答案,因为这里的最后一次编辑/评论建议使用一种不...

问题描述:

我经常在 Python 解释器中测试模块,一旦发现错误,就会快速更新 .py 文件。但是,如何让错误反映到解释器中呢?到目前为止,我一直都是退出解释器再重新进入,因为重新导入文件对我来说不起作用。


解决方案 1:

Python3 的更新:(引用自已经回答的答案,因为这里的最后一次编辑/评论建议使用一种不推荐使用的方法)

在 Python 3 中,reload被移至imp模块。在 3.4 中,已被弃用,imp取而代之的是,并被添加到后者。当面向 3 或更高版本时,请在调用时引用相应的模块或导入它。importlib`reload`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

解决方案 2:

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

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

最好还是用它importlib.reload()代​​替。

解决方案 3:

到目前为止,我已经退出并重新进入解释器,因为重新导入文件对我来说不起作用。

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

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

因此,如果您有一个a依赖于模块的模块b,并且b它发生了变化,那么您必须“重新加载 b”,然后“重新加载 a”。如果您有两个相互依赖的模块(当这些模块属于同一个包时这种情况非常常见),那么您不能同时重新加载它们:如果您重新加载,p.a它将获得对旧模块的引用p.b,反之亦然。唯一的方法是通过从中删除它们的项目来同时卸载它们sys.modules,然后再导入它们。这很麻烦,并且在模块条目为 None 作为失败相对导入标记时存在一些实际陷阱。

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

总而言之:除了最简单的情况(即一个独立脚本加载一个独立模块)之外,其他所有情况reload()都很难做到正确;如果如您所暗示的那样,您正在使用“包”,那么继续循环解释器可能会更好。

解决方案 4:

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

>>> import my_stuff

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

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

您将获得一个全新的、重新加载的 my_stuff。

解决方案 5:

无论导入模块多少次,您都会获得相同的模块副本sys.modules- 该副本最初是加载的import mymodule

我回答得晚了,因为上面/之前的每个答案都有一点答案,所以我试图用一个答案来总结所有内容。

使用内置函数

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

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

对于Python 3.4 - 在 Python 3.4 中imp已被弃用,转而使用importlibieimportlib.reload(mymodule)

几点注意事项

  • 重新加载内置模块或动态加载模块通常没什么用。不建议重新加载sys__main__和其他关键模块。builtins

  • 很多情况下,扩展模块并非设计为可多次初始化,并且在重新加载时可能会以任意方式失败。如果一个模块使用from……从另一个模块导入对象import,则调用reload()另一个模块并不会重新定义从其导入的对象——解决这个问题的一种方法是重新执行该from语句,另一种方法是使用import限定名(module.name)。

  • 如果模块实例化了某个类的实例,则重新加载定义该类的模块不会影响实例的方法定义——它们将继续使用旧的类定义。派生类也是如此。


外部包

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

xreload - 通过在临时命名空间中执行模块,然后就地修补类、方法和函数来实现。这样就无需修补实例。新的对象将被复制到目标命名空间中。

livecoding - 代码重载允许正在运行的应用程序根据其使用的 Python 脚本的更改来改变其行为。当该库检测到 Python 脚本已被修改时,它会重新加载该脚本,并用新加载的版本替换之前可用的对象。作为一种工具,它可以帮助程序员避免工作流程中断以及随之而来的注意力分散。它使他们能够保持流畅的状态。以前,他们可能需要重新启动应用程序才能使更改的代码生效,而现在这些更改可以立即应用。

解决方案 6:

简短回答:

尝试使用reimport:Python 的全功能重新加载。

更长的答案:

看起来这个问题是在reimport发布之前提出/回答的,reimport 自称是“Python 的全功能重新加载”:

此模块旨在成为 Python reload 函数的全功能替代品。其目标是为长期运行的应用程序所使用的 Python 插件和扩展提供 reload 功能。

Reimport 目前支持 Python 2.4 到 2.6。

就其本质而言,这不是一个完全可以解决的问题。此模块的目标是使最常见的更新类型能够正常工作。它还允许各个模块和软件包协助完成此过程。有关更详细的描述,请参阅概述页面。

注意:尽管reimport明确支持 Python 2.4 到 2.6,但我一直在 2.7 上尝试过,而且它似乎运行良好。

解决方案 7:

基本上像 allyourcode 的答案那样重新加载。但它不会改变已实例化对象或引用函数的底层代码。扩展他的答案:

#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

解决方案 8:

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

>>> del mymodule
>>> import mymodule

解决方案 9:

import sys
del sys.modules['module_name']

解决方案 10:

请参阅此处,了解有关如何不重新加载依赖模块以及可能产生的影响的详细说明:

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

pyunit 解决这个问题的方法是,通过重写 import 来跟踪依赖模块,然后从 sys.modules 中删除每个依赖模块,再重新导入。不过,他们或许可以直接重新加载它们。

解决方案 11:

dragonfly 的答案对我有用(python 3.4.3)。

import sys
del sys.modules['module_name']

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

exec(open("MyClass.py").read(), globals())
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用