2009-10-04 209 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