这是一个非常基本的问题 - 但我无法通过在线搜索找到答案。
我使用python来控制ArcGIS,我有一个简单的python脚本,可以调用一些预先编写的代码。
但是,当我对预先编写的代码进行更改时,它似乎不会导致任何更改。我导入了这个模块,并尝试刷新它,但没有任何反应。
我甚至将它调用的文件移动到另一个位置,脚本仍能正常工作。我昨天做的一件事是我添加了所有我的python文件到sys路径的文件夹(使用sys.append('path')),我想知道这是否有所作为。
提前致谢,对于草率的术语感到抱歉。
答案 0 :(得分:32)
目前还不清楚“刷新”是什么意思,但Python的正常行为是你需要重新启动软件才能重新审视Python模块并重新读取它。
如果您的更改即使在重新启动后仍未处理,则这是由于以下两个错误之一:
即使不使用reload()命令重新启动软件,也可以通过重新加载重新读取文件。请注意,指向模块中任何内容的任何变量都需要在重新加载后重新导入。像这样:
import themodule
from themodule import AClass
reload(themodule)
from themodule import AClass
答案 1 :(得分: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
为止。
答案 2 :(得分:3)
在从模块中导入所有对象时使用以下内容以确保web2py正在使用我当前的代码:
import buttons
import table
reload(buttons)
reload(table)
from buttons import *
from table import *
答案 3 :(得分: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 :(得分: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()
)
答案 5 :(得分:0)
我遇到了为ArcGIS 10.2创建地理处理脚本的完全相同的问题。我有一个python工具箱脚本,一个工具脚本,然后是一个通用脚本。我在工具中有一个Dev / Test / Prod参数,可以控制运行代码的版本。 Dev会在dev文件夹中运行代码,从test文件夹测试并从prod文件夹中生成prod。从ArcCatalog运行该工具时,不会运行对公共开发脚本的更改。关闭ArcCatalog没有任何区别。即使我选择了Dev或Test,它也总是从prod文件夹运行。
将重新加载(myCommonModule)添加到工具脚本解决了这个问题。
答案 6 :(得分: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?
对于早期的python版本(如2.x),请使用如上所述的内置重载功能。 更好的方法是使用ipython3,因为它提供了自动重新加载功能。