python refresh/reload
这是一个非常基本的问题,但我还没有通过网上搜索找到答案。
我使用python来控制arcgis,我有一个简单的python脚本,它调用一些预先编写的代码。
但是,当我对预先编写的代码进行更改时,似乎不会导致任何更改。我导入了这个模块,并尝试刷新它,但什么也没有发生。
我甚至把它调用的文件移到了另一个位置,脚本仍然可以正常工作。我昨天做的一件事是,我添加了一个文件夹,其中所有的python文件都在sys路径中(使用sys.append("path")),我想知道这是否起了作用。
事先谢谢,对于这个草率的术语感到抱歉。
不清楚"刷新"是什么意思,但python的正常行为是,您需要重新启动软件,以便它重新查看python模块并重新阅读它。
如果重新启动后仍不处理您的更改,则这是由于以下两个错误之一造成的:
即使不使用reload()命令重新启动软件,也可以使用reload重新读取文件。请注意,任何指向模块中任何内容的变量都需要在重新加载后重新导入。像这样:
1 2 3 4 5 | import themodule from themodule import AClass reload(themodule) from themodule import AClass |
。
一种方法是调用
示例:下面是
1 2 | def bar(): return 1 |
在交互式会话中,我可以做到:
1 2 3 | >>> import foo >>> foo.bar() 1 |
号
然后在另一个窗口中,我可以将
1 2 | def bar(): return"Hello" |
在交互会话中,调用
1 2 3 4 | >>> reload(foo) <module 'foo' from 'foo.py'> >>> foo.bar() 'Hello' |
。
调用
python不每次都从源模块读取的一个原因是加载一个模块(相对)比较昂贵——如果您有一个300kb的模块,并且只使用了文件中的一个常量,会怎么样?python加载一次模块并将其保存在内存中,直到您使用
如果您在ipython shell中运行,那么存在一些魔法命令。
IPython文档包含这个称为自动加载扩展的功能。
最初,我从JonathanMarch关于这个主题的博客文章中找到了这个解决方案(见链接中的第3点)。
基本上,您需要做的就是以下操作,您所做的更改会在保存后自动反映出来:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
在从模块中导入所有对象时,我使用了以下方法以确保Web2py使用了我的当前代码:
1 2 3 4 5 6 | import buttons import table reload(buttons) reload(table) from buttons import * from table import * |
。
我不太确定这就是你的意思,所以别犹豫纠正我。您在程序中导入了一个模块,我们称之为mymodule.py,但当您更改其内容时,您看不到区别吗?
python不会在mymodule.py中查找每次使用时的更改,它将第一次加载它,将其编译为字节码并在内部保存它。它通常还保存编译的字节码(mymodule.pyc)。下次启动程序时,它将检查mymodule.py是否比mymodule.pyc更新,并在必要时重新编译。
如果需要,可以显式重新加载模块:
1 2 3 4 5 6 | import mymodule [... some code ...] if userAskedForRefresh: reload(mymodule) |
当然,它比这更复杂,并且您可能会产生副作用,这取决于您对其他模块的程序所做的操作,例如,如果变量依赖于MyModule中定义的类。
或者,可以使用
对于不同版本的python,情况会有所不同。下面是Python3.4或更高版本的示例:
1 2 3 4 5 6 7 8 9 | 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,因为它提供了自动加载功能。
我在为Arcgis10.2创建地理处理脚本时遇到了同样的问题。我有一个python工具箱脚本,一个工具脚本,然后是一个公共脚本。我在工具中有一个dev/test/prod的参数,可以控制运行的代码版本。dev将运行dev文件夹中的代码,test from test文件夹和prod from prod文件夹中的prod。从ArcCatalog运行该工具时,对公共dev脚本的更改将不会运行。关闭arcCatalog没有什么不同。即使我选择了dev或test,它也总是从prod文件夹运行。
向工具脚本添加reload(mycommonmodule)解决了这个问题。