python刷新/重新加载

时间:2009-10-04 18:23:26

标签: python refresh reload

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

我使用python来控制ArcGIS,我有一个简单的python脚本,可以调用一些预先编写的代码。

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

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

提前致谢,对于草率的术语感到抱歉。

7 个答案:

答案 0 :(得分:32)

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

如果您的更改即使在重新启动后仍未处理,则这是由于以下两个错误之一:

  1. pyc文件的时间戳不正确,将来有一段时间。
  2. 您实际上是在编辑错误的文件。
  3. 即使不使用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,因为它提供了自动重新加载功能。