29

这是一个非常基本的问题 - 但我无法通过在线搜索找到答案。

我正在使用 python 来控制 ArcGIS,并且我有一个简单的 python 脚本,它调用了一些预先编写的代码。

但是,当我对预先编写的代码进行更改时,它似乎不会导致任何更改。我导入了这个模块,并尝试刷新它,但没有任何反应。

我什至将它调用的文件移到了另一个位置,脚本仍然可以正常工作。我昨天做的一件事是我将所有 python 文件所在的文件夹添加到 sys 路径(使用 sys.append('path') ),我想知道这是否有所作为。

在此先感谢,并为草率的术语感到抱歉。

4

7 回答 7

34

不清楚“刷新”是什么意思,但 Python 的正常行为是您需要重新启动软件才能重新审视 Python 模块并重新阅读它。

如果即使重新启动后您的更改也没有得到处理,那么这是由于以下两个错误之一:

  1. pyc 文件上的时间戳不正确,并且在未来某个时间。
  2. 您实际上正在编辑错误的文件。

即使不使用 reload() 命令重新启动软件,您也可以使用 reload 重新读取文件。请注意,任何指向模块中任何内容的变量都需要在重新加载后重新导入。像这样的东西:

import themodule
from themodule import AClass

reload(themodule)
from themodule import AClass
于 2009-10-04T18:46:24.750 回答
20

一种方法是调用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也是确保您的模块是最新的一种方法。它不一定是最有效的(您最好检查文件的最后修改时间或在您之前使用pyinotifyreload之类的东西),但它确实可以快速实现。

Python 不每次都从源模块读取的一个原因是加载模块(相对)昂贵——如果您有一个 300kb 的模块并且您只使用文件中的单个常量怎么办?Python 会加载一次模块并将其保存在内存中,直到您使用reload它为止。

于 2009-10-04T18:40:08.303 回答
3

从模块中导入所有对象时,我使用了以下内容以确保 web2py 正在使用我当前的代码:

import buttons
import table
reload(buttons)
reload(table)
from buttons import *
from table import *
于 2011-09-20T03:39:59.347 回答
3

如果您在 IPython shell 中运行,那么存在一些神奇的命令。

IPython 文档介绍了这个称为autoreload 扩展的特性。

最初,我从Jonathan March 关于这个主题的博客文章中找到了这个解决方案(请参阅该链接中的第 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
于 2016-03-13T15:57:10.057 回答
1

我不确定这就是你的意思,所以请不要犹豫,纠正我。您正在程序中导入一个模块 - 我们称之为 mymodule.py - 但是当您更改其内容时,您看不到区别吗?

Python 不会在每次使用时查找 mymodule.py 中的更改,它会第一次加载它,将其编译为字节码并保留在内部。它通常还会保存已编译的字节码(mymodule.pyc)。下次启动程序时,它会检查 mymodule.py 是否比 mymodule.pyc 更新,并在必要时重新编译。

如果需要,可以显式重新加载模块:

import mymodule

[... some code ...]

if userAskedForRefresh:
    reload(mymodule)

当然,它比这更复杂,并且您可能会产生副作用,具体取决于您对程序执行的其他模块的操作,例如变量是否依赖于 mymodule.xml 中定义的类。

或者,您可以使用execfile函数(或exec(), eval(), compile()

于 2009-10-04T18:40:27.237 回答
0

我在为 ArcGIS 10.2 创建地理处理脚本时遇到了完全相同的问题。我有一个 python 工具箱脚本、一个工具脚本和一个通用脚本。我在工具中有一个用于 Dev/Test/Prod 的参数,可以控制运行哪个版本的代码。Dev 将在 dev 文件夹中运行代码,从 test 文件夹中进行测试,从 prod 文件夹中运行 prod。从 ArcCatalog 运行工具时,对通用开发脚本的更改不会运行。关闭 ArcCatalog 没有任何区别。即使我选择了 Dev 或 Test,它也会始终从 prod 文件夹运行。

将 reload(myCommonModule) 添加到工具脚本解决了这个问题。

于 2014-12-04T16:31:15.313 回答
0

对于不同版本的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?

对于像 2.x 这样的早期 python 版本,使用如上所述的内置重新加载功能。更好的是使用 ipython3,因为它提供了自动重载功能。

于 2018-10-02T15:11:33.660 回答