2009-10-04 203 views
26

这是一个非常基本的问题 - 但我一直无法通过在线搜索找到答案。python刷新/重新加载

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

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

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

在此先感谢,并对于马虎的术语感到抱歉。

回答

31

目前还不清楚你的意思“刷新”了什么,但是Python的正常行为,你需要重新启动,该软件在Python模块上重新审视并重新阅读它。

如果所做的更改不会采取即使重启后的护理,那么这两个错误导致的:

  1. 的PYC文件的时间戳不正确,在未来的一段时间。
  2. 您实际上正在编辑错误的文件。

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

import themodule 
from themodule import AClass 

reload(themodule) 
from themodule import AClass 
+0

我有一个类似的问题,这没有把戏。我注意到,删除第一个'从模块导入AClass'仍然有诀窍。任何理由都有? – pentandrous 2015-09-28 21:09:31

+0

解决问题并不是“诀窍”,而你的实际问题来自其他地方。您应该尝试解决这个问题。 – 2015-09-29 10:45:08

19

完成此操作的一种方法是致电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它。

1

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

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

如果需要,你可以明确地重新加载模块:

import mymodule 

[... some code ...] 

if userAskedForRefresh: 
    reload(mymodule) 

当然,比这更复杂,你可能取决于你与你有关的其他程序做什么副作用模块,例如,如果变量取决于mymodule中定义的类。

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

+0

谢谢大家对你的答案。我曾尝试使用重新加载,并关闭/重新打开该程序。 问题原来是由原始代码中被命名为相同的文件引起的。即使我以为我是从一个新的位置导入它,它仍然使用旧文件。 – womble 2009-10-04 19:30:28

3

我用从一个模块中导入所有对象时,确保web2py的使用我当前的代码如下:

import buttons 
import table 
reload(buttons) 
reload(table) 
from buttons import * 
from table import * 
0

我有完全相同的问题,创造一个地理处理脚本ArcGIS 10.2。我有一个Python工具箱脚本,一个工具脚本,然后是一个通用脚本。我在工具中有一个Dev/Test/Prod参数,它可以控制运行哪个版本的代码。 Dev会运行dev文件夹中的代码,从测试文件夹中进行测试并从prod文件夹中执行prod。当工具从ArcCatalog运行时,通用开发脚本的更改将不会运行。关闭ArcCatalog没有任何区别。即使我选择开发或测试,它始终会从prod文件夹运行。

将重新加载(myCommonModule)添加到工具脚本解决了此问题。

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