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 应用程序时如何自动刷新浏览器?

重新加载/刷新谷歌地图

UINavigationbar 重新加载/刷新按钮代码

Laravel Livewire 组件在刷新后不会自动刷新/重新加载

每次刷新页面时重新加载数据表

Vue刷新页面重新加载