python刷新/重新加载
Posted
技术标签:
【中文标题】python刷新/重新加载【英文标题】:python refresh/reload 【发布时间】:2010-12-03 18:35:02 【问题描述】:这是一个非常基本的问题 - 但我无法通过在线搜索找到答案。
我正在使用 python 来控制 ArcGIS,并且我有一个简单的 python 脚本,它调用了一些预先编写的代码。
但是,当我对预先编写的代码进行更改时,它似乎不会导致任何更改。我导入了这个模块,并尝试刷新它,但没有任何反应。
我什至将它调用的文件移到了另一个位置,脚本仍然可以正常工作。我昨天做的一件事是我将所有 python 文件所在的文件夹添加到 sys 路径(使用 sys.append('path') ),我想知道这是否有所作为。
在此先感谢,对于草率的术语,我们深表歉意。
【问题讨论】:
【参考方案1】:不同版本的python情况会有所不同。 下面以python 3.4及以上版本为例:
hello import hello_world
#Calls hello_world function
hello_world()
HI !!
#Now changes are done and reload option is needed
import importlib
importlib.reload(hello)
hello_world()
How are you?
对于较早的 python 版本,如 2.x,使用如上所述的内置重新加载功能。 更好的是使用 ipython3,因为它提供了自动重载功能。
【讨论】:
【参考方案2】:一种方法是致电reload
。
例子:这里是foo.py
的内容:
def bar():
return 1
在交互式会话中,我可以这样做:
>>> import foo
>>> foo.bar()
1
然后在另一个窗口中,我可以将foo.py
更改为:
def bar():
return "Hello"
回到交互式会话,调用foo.bar()
仍然返回 1,直到我这样做:
>>> reload(foo)
<module 'foo' from 'foo.py'>
>>> foo.bar()
'Hello'
调用reload
是一种 方法来确保您的模块是最新的,即使磁盘上的文件已更改。它不一定是最有效的(您最好检查文件的最后修改时间,或者在 reload
之前使用类似 pyinotify 的东西),但它的实施速度肯定很快。
Python 不每次都从源模块读取的一个原因是加载模块(相对)昂贵——如果您有一个 300kb 的模块并且您只使用文件中的单个常量怎么办? Python 加载一个模块一次并将其保存在内存中,直到您 reload
它。
【讨论】:
【参考方案3】:如果您在 IPython shell 中运行,那么存在一些神奇的命令。
IPython 文档介绍了这个称为autoreload extension 的功能。
最初,我从Jonathan March's blog posting on this very subject 找到了这个解决方案(请参阅该链接中的第 3 点)。
基本上,您只需执行以下操作,您所做的更改会在您保存后自动反映出来:
In [1]: %load_ext autoreload
In [2]: %autoreload 2
In [3]: Import MODULE
In [4]: my_class = Module.class()
my_class.printham()
Out[4]: ham
In [5]: #make changes to printham and save
In [6]: my_class.printham()
Out[6]: hamlet
【讨论】:
【参考方案4】:我在为 ArcGIS 10.2 创建地理处理脚本时遇到了完全相同的问题。我有一个 python 工具箱脚本、一个工具脚本和一个通用脚本。我在工具中有一个用于 Dev/Test/Prod 的参数,用于控制运行哪个版本的代码。 Dev 将在 dev 文件夹中运行代码,从 test 文件夹中进行测试,从 prod 文件夹中运行 prod。从 ArcCatalog 运行工具时,对通用开发脚本的更改不会运行。关闭 ArcCatalog 没有任何区别。即使我选择了 Dev 或 Test,它也会始终从 prod 文件夹运行。
在工具脚本中添加 reload(myCommonModule) 解决了这个问题。
【讨论】:
【参考方案5】:在从模块中导入所有对象时,我使用了以下内容,以确保 web2py 正在使用我当前的代码:
import buttons
import table
reload(buttons)
reload(table)
from buttons import *
from table import *
【讨论】:
【参考方案6】:不清楚您所说的“刷新”是什么意思,但 Python 的正常行为是您需要重新启动软件才能重新审视 Python 模块并重新读取它。
如果您的更改在重新启动后仍未得到处理,则这是由于以下两个错误之一:
-
pyc 文件上的时间戳不正确,并且在未来某个时间。
您实际上是在编辑错误的文件。
即使不使用 reload() 命令重新启动软件,您也可以通过 reload 重新读取文件。请注意,任何指向模块中任何内容的变量都需要在重新加载后重新导入。像这样的:
import themodule
from themodule import AClass
reload(themodule)
from themodule import AClass
【讨论】:
我遇到了类似的问题,这成功了。我注意到删除第一个from themodule import AClass
仍然有效。有什么理由两者兼得?
解决问题并不是真正的“技巧”,而您的实际问题来自其他地方。你应该尝试解决这个问题。【参考方案7】:
我不太确定这就是你的意思,所以请不要犹豫,纠正我。您正在程序中导入一个模块 - 我们称之为 mymodule.py - 但是当您更改其内容时,您看不到区别吗?
Python 不会在每次使用 mymodule.py 时查找更改,它会在第一次加载它,将其编译为字节码并保留在内部。它通常还会保存已编译的字节码(mymodule.pyc)。下次启动程序时,它会检查 mymodule.py 是否比 mymodule.pyc 更新,并在必要时重新编译。
如果需要,可以显式重新加载模块:
import mymodule
[... some code ...]
if userAskedForRefresh:
reload(mymodule)
当然,它比这更复杂,并且您可能会产生副作用,具体取决于您对程序执行的其他模块的操作,例如,如果变量依赖于 mymodule 中定义的类。
或者,您可以使用execfile
函数(或exec()
、eval()
、compile()
)
【讨论】:
谢谢大家的回答。我尝试过使用重新加载,并关闭/重新打开程序。问题原来是由在原始代码中命名相同的文件引起的。即使我以为我是从新位置导入它,它仍在使用旧文件。以上是关于python刷新/重新加载的主要内容,如果未能解决你的问题,请参考以下文章
使用 Python 开发 Flask 应用程序时如何自动刷新浏览器?