第十一章 使用加載項自定義ArcGIS界面 ||| 附錄A 自動執(zhí)行Python腳本
我們將在本章介紹以下案例:
- 查看Python默認(rèn)的錯誤消息
- 添加Python異常處理語句結(jié)構(gòu)(try/except/finally)
- 調(diào)用GetMessages()函數(shù)獲取工具消息
- 使用嚴(yán)重性級別篩選工具消息
- 調(diào)用GetMessage()返回單個消息
- 測試并響應(yīng)特定錯誤消息
引言
ArcGIS地理處理工具和函數(shù)執(zhí)行過程中會返回不同的消息虱肄。這些消息包括信息性消息邻邮,也可能含有提示警告信息或錯誤狀況堡牡,這些警告或錯誤的出現(xiàn)意味著工具執(zhí)行完畢后沒有出現(xiàn)預(yù)期的結(jié)果或工具執(zhí)行完全失敗篙梢。不過這些消息并不是以消息框的形式顯示,你需要調(diào)用許多不同的ArcPy函數(shù)來訪問這些消息酪耕。到目前為止呜象,我們都忽略了這些消息、提醒和錯誤晚岭。主要是因為希望你能專注于學(xué)習(xí)一些基本的概念鸥印,而沒有增加額外的代碼復(fù)雜度,而這些消息有關(guān)的代碼對于創(chuàng)建能夠處理錯誤狀況的地理處理腳本是非常有必要的。現(xiàn)在是時候來學(xué)習(xí)如何在Python中創(chuàng)建異常處理語句結(jié)構(gòu)辅甥。這些腳本可以處理在腳本執(zhí)行過程中生成的提示警告信息酝润,錯誤信息和通用信息。這些異常處理語句會讓你的腳本更加靈活而且更不容易出現(xiàn)錯誤璃弄。你已經(jīng)使用了基本的try
和except
語句塊來執(zhí)行一些簡單的錯誤處理操作要销。在本章中,我們會介紹更多關(guān)于異常處理語句的細節(jié)內(nèi)容夏块。
查看Python默認(rèn)的錯誤消息
默認(rèn)情況下疏咐,Python在腳本中一旦遇到問題就會生成錯誤消息。這些錯誤消息的內(nèi)容對于運行腳本的最終用戶來講并非總是那么明確具體脐供。盡管如此浑塞,查看這些原始消息還是很有價值的。在后面的案例中政己,我們會使用Python錯誤處理語句結(jié)構(gòu)來了解錯誤信息以及能夠在必要時針對錯誤和異常情況作出反饋酌壕。
Getting ready
本案例中,我們會創(chuàng)建并運行一個有錯誤的腳本歇由。在腳本中我們不會添加任何地理處理或Python異常處理結(jié)構(gòu)卵牍。這樣我們就能夠看到Python自身返回的錯誤消息。
How to do it...
按照以下步驟來查看Python自身生成的錯誤消息沦泌,該消息是由于工具在執(zhí)行過程中遇到錯誤生成的:
1.打開IDLE糊昙,創(chuàng)建一個新的腳本。
2.腳本保存為C:\ArcpyBook\Ch12\ErrorHandling.py
文件谢谦。
3.導(dǎo)入arcpy
模塊:
import arcpy
4.設(shè)置工作空間路徑:
arcpy.env.worksapce = "C:/ArcpyBook/data"
5.調(diào)用Buffer
工具释牺。Buffer
工具需要一個緩沖距離作為其中一個參數(shù)。在代碼中我們故意舍掉距離參數(shù):
arcpy.Buffer_analysis("Streams.shp","Streams_Buff.shp")
6.運行腳本回挽。你會看到如下結(jié)果顯示:
Traceback (most recent call last):
File "<string>", line 3, in <module>
arcpy.Buffer_analysis("Streams.shp","Stream_buffer.shp")
File "c:\program files\(x86)\arcgis\desktop10.1\arcpy\arcpy\analysis.py", line 687, in Buffer
raise e
ExecuteError: Failed to execute. Parameters are not valid.
ERROR 000735: Distance [value or field]: Value is required
Failed to execute (Buffer).
How it works...
輸出的錯誤消息中的內(nèi)容似乎沒什么有用的信息没咙。如果是一個有經(jīng)驗的程序員,通常能夠找到問題在于我們沒有提供緩沖距離參數(shù)厅各。然而镜撩,很多情況下,返回的錯誤消息并不會給你解決問題提供很多幫助信息队塘。代碼錯誤在編程中是不可避免的袁梗。如何理解這些稱為異常的錯誤是非常重要的。你可以使用Python異常處理語句結(jié)構(gòu)來有步驟地處理這些錯誤憔古,而這些語句結(jié)構(gòu)會查看arcpy
生成的異常信息并作出相對應(yīng)的反饋遮怜。如果缺少這些語句結(jié)構(gòu),腳本在執(zhí)行過程中很可能會隨時中斷或失敗鸿市,從而讓最終用戶懊惱锯梁。
添加Python異常處理結(jié)構(gòu)(try/except/finally)
Python內(nèi)置的異常處理語句結(jié)構(gòu)能夠捕獲腳本執(zhí)行中生成的錯誤消息即碗。你可以利用這些錯誤信息為最終用戶提供一個更為明確的消息內(nèi)容并在必要時候作出反饋。
Getting ready
異常是代碼中的非正衬暗剩或錯誤狀況剥懒。異常處理語句能夠捕獲并處理代碼中的錯誤,可以讓程序能夠從錯誤狀況中恢復(fù)合敦。除了用來處理錯誤初橘,異常處理語句還可用于其他方面,比如事件提醒和特殊情況處理等充岛。
Python的異常有兩種發(fā)生方式保檐。異常既可以捕獲也可以觸發(fā)。代碼中發(fā)生錯誤時崔梗,Python會自動觸發(fā)一個異常夜只,這類異常有可能會在代碼中處理。作為一名程序員需要捕獲自動觸發(fā)的異常蒜魄。異常還可以通過代碼方式進行人工觸發(fā)扔亥。這種情況下,你需要提供一個異常處理機制來捕獲這類人工觸發(fā)的異常权悟。你可以使用raise
語句來實現(xiàn)觸發(fā)異常砸王。
try/except
語句是Python中用來處理異常的一組完整的組合語句。try
語句結(jié)構(gòu)是以try
作為首行代碼峦阁,后面緊跟一組縮進的語句塊,之后是一個或多個可選的except
語句用來命名捕獲的異常耘成,最后是一個可選的else
語句和finally
語句榔昔。
下面以try/except/else
語句結(jié)構(gòu)來說明運行機制。在try
語句中瘪菌,Python就會知道你現(xiàn)在正處于一個try
語句塊中撒会,一旦有異常發(fā)生就會直接交給后面的except
語句進行處理。try
語句塊中的每一行代碼都會執(zhí)行师妙。假如沒有異常發(fā)生诵肛,代碼就會跳至else
語句來執(zhí)行else
語句中的代碼然后再執(zhí)行整個try/except/else
語句塊后面的代碼。如果有異常發(fā)生默穴,Python會查找相匹配的異常語句怔檩,如果找到了匹配的except
語句,那么就會執(zhí)行該except
語句中的代碼蓄诽,之后執(zhí)行整個try/except/else
語句塊后面的代碼薛训。在這種情況下else
語句則不會執(zhí)行。如果沒有找到匹配的except
語句仑氛,那么在這種情況下乙埃,異常提交給最高層try
語句中闸英。這將導(dǎo)致一個無法處理的異常,也就會遇到我們在本章第一個案例中看到的錯誤消息介袜。
本案例中甫何,我們會添加一些基本的Python異常處理結(jié)構(gòu)語句。在本案例中遇伞,我們先介紹一個非常簡單的try/except
語句結(jié)構(gòu)沛豌。
How to do it...
按照以下步驟在腳本中添加Python錯誤處理語句:
1.在IDLE中打開C:\ArcpyBook\Ch12\ErrorHandling.py
文件。
2.在腳本中添加try/except
語句:
import arcpy
try:
arcpy.env.workspace = "C:/ArcpyBook/data"
arcpy.Buffer_analysis("Streams.shp","Streams_Buff.shp")
except:
print "Error"
3.保存并修改腳本赃额。你會看到一條簡答的消息顯示Error
加派。這條信息沒有比我們在第一個案例中見到的結(jié)果更有幫助。事實上該消息的有用信息更少跳芳。本案例的目的只是介紹try/except
語句結(jié)構(gòu)芍锦。
How it works...
這是一個非常簡單的結(jié)構(gòu)。try
語句塊中的所有語句都會執(zhí)行飞盆。如果異常發(fā)生娄琉,語句會跳至except
部分來打印錯誤消息,在本案例中也就是一個簡單的Error
消息吓歇。如我之前所說孽水,盡管這種消息對用戶難言有價值,但希望可以讓你對try/except
語句的工作方式有個基本了解城看,同時作為一名程序員女气,你需要更好地了解程序反饋的任何錯誤。在下一個案例中测柠,你會學(xué)習(xí)如何在異常處理結(jié)構(gòu)中獲取由地理處理工具生成的消息炼鞠。
There's more...
另外一種try
語句類型是try/finally
語句,該語句可用于執(zhí)行終止操作轰胁。當(dāng)finally
語句出現(xiàn)在try
語句塊中使谒主,無論是否發(fā)生異常或錯誤赃阀,finally
語句部分在最后都會執(zhí)行霎肯。如果有異常發(fā)生,Python會執(zhí)行try
語句塊榛斯,之后執(zhí)行finally
語句塊观游,然后接著執(zhí)行整個try
語句后面的代碼查描。如果執(zhí)行過程中沒有出現(xiàn)異常苟弛,Python會執(zhí)行try
語句塊,之后執(zhí)行finally
語句塊艰赞。不管錯誤是否發(fā)生都需要確保執(zhí)行某項操作時候意述,finally
語句會非常有用提佣。
調(diào)用GetMessages()獲取工具消息
ArcPy提供的GetMessages()
函數(shù)用于獲取ArcGIS工具執(zhí)行過程中生成的消息吮蛹。這些消息既包括像工具執(zhí)行的起始時間這樣的信息性消息,也包括由于未得到預(yù)期結(jié)果或工具執(zhí)行失敗生成的警告信息和錯誤信息拌屏。
Getting ready
工具執(zhí)行過程中會生成各種各樣的消息潮针。這些消息包括消息性消息,比如工具執(zhí)行的開始和結(jié)束時間倚喂,工具使用的參數(shù)值以及進度消息每篷。除此之外,工具還會生成警告消息和錯誤消息端圈。這些消息可以通過Python腳本來讀取焦读,同時還可以編寫代碼來處理出現(xiàn)的警告或錯誤消息。
ArcPy會保存上一次執(zhí)行的工具生成的消息舱权,你可以調(diào)用GetMessages()
函數(shù)來讀取這些消息矗晃,GetMessages()
會返回一個包含了工具在上一次執(zhí)行中生成的所有消息的字符串。你可以使用嚴(yán)重性參數(shù)來篩選字符串以返回像警告消息或錯誤消息這樣特定類型的消息宴倍。第一條消息通常是工具的名稱张症,最后一條信息是工具執(zhí)行的開始和結(jié)束時間。
在本案例中鸵贬,你會添加一行except
語句俗他,該語句用來打印關(guān)于當(dāng)前運行工具執(zhí)行過程中具體消息。
How to do it...
按照以下步驟來學(xué)習(xí)如何添加GetMessages()
函數(shù)來生成工具執(zhí)行返回的消息列表阔逼。
1.在IDLE中打開C:\ArcpyBook\Ch12\ErrorHandling.py
文件兆衅。
2.添加GetMessages()
函數(shù):
import arcpy
try:
arcpy.env.workspace = "C:/ArcpyBook/data"
arcpy.Buffer_analysis("Streams.shp","Streams_Buff.shp")
except:
print arcpy.GetMessages()
3.保存并運行腳本。這一次返回的錯誤消息應(yīng)該會更為具體颜价。你會注意到還有其他類型的消息返回涯保,比如腳本執(zhí)行的開始和結(jié)束的時間等。
Executing: Buffer c:/ArcpyBook/data\Streams.shp c:/ArcpyBook/data\Streams_Buff.shp # FULL ROUND NONE #
Start Time: Tue Nov 13 22:23:04 2012
Failed to execute. Parameters are not valid.
ERROR 000735: Distance [value or field]: Value is required
Failed to execute (Buffer).
Failed at Tue Nov 13 22:23:04 2012 (Elapsed Time: 0.00 seconds)
How it works...
GetMessages()
函數(shù)返回上一次執(zhí)行工具過程中生成的所有的消息周伦。這里需要要強調(diào)的是該函數(shù)僅返回上一次執(zhí)行的工具生成的消息。如果腳本中有多個工具執(zhí)行的話那就需要留意這一點未荒。歷史記錄中執(zhí)行的工具過程生成的消息不能通過該函數(shù)獲取专挪。不過,你可以使用Result
對象獲取歷史記錄中工具運行的信息片排。
使用嚴(yán)重性級別篩選工具消息
如前面提到的那樣寨腔,所有的工具生成的消息可以分為消息性消息,警告消息和錯誤消息率寡。GetMessages()
函數(shù)可接受一個嚴(yán)重性級別參數(shù)用來篩選返回的消息迫卢。舉個例子,你可能只對工具執(zhí)行過程中生成的錯誤消息感興趣冶共,對消息性消息和警告信息不感興趣乾蛤。調(diào)用GetMessages(2)
語句返回的消息中就僅包含錯誤消息每界。
Getting ready
任何消息都可以被歸類到三種消息類型中一類中,消息類型可以通過一個嚴(yán)重性級別來指定家卖。信息性消息(Informational messages)提供與工具執(zhí)行有關(guān)的描述性信息眨层,比如工具執(zhí)行進度,工具執(zhí)行的開始和結(jié)束時間上荡,輸出數(shù)據(jù)特征等等趴樱。消息性消息的嚴(yán)重性級別用數(shù)字0
來表示。警告消息(Warning messages)表示工具執(zhí)行過程中出現(xiàn)的問題可能影響輸出結(jié)果的時候生成酪捡。警告信息的嚴(yán)重性級別用數(shù)字1
表示叁征,同時并不會中止正在執(zhí)行的工具。最后一個類型是錯誤消息(error messages),該類型消息的嚴(yán)重性級別實用數(shù)字2
表示逛薇。錯誤消息表示有嚴(yán)重事件阻止工具運行捺疼。工具執(zhí)行過程中會生成多個消息,這些消息都保存在列表中金刁。更多關(guān)于消息嚴(yán)重性的信息見下圖帅涂。在本案例中,你將學(xué)習(xí)如何調(diào)用GetMessages()
函數(shù)來篩選工具生成的消息尤蛮。
How to do it...
篩選工具返回的消息非常簡單媳友。你只要將想要返回的嚴(yán)重性級別相對應(yīng)的數(shù)字作為參數(shù)提供給GetMessages()
函數(shù)即可。
1.在IDLE中打開C:\ArcpyBook\Ch12\ErrorHandling.py
文件产捞。
2.將數(shù)值2
最為參數(shù)傳遞給GetMessages()
函數(shù):
import arcpy
try:
arcpy.env.workspace = "C:/ArcpyBook/data"
arcpy.Buffer_analysis("Streams.shp","Streams_Buff.shp")
except:
print arcpy.GetMessages(2)
3.保存并運行腳本會看到如下結(jié)果:
Failed to execute. Parameters are not valid.
ERROR 000735: Distance [value or field]: Value is required
Failed to execute (Buffer).
How it works...
如前所述醇锚,GetMessages()
函數(shù)可接受0
,1
,2
整數(shù)值參數(shù)。數(shù)值0
表示返回消息性消息坯临,而數(shù)值1
表示返回警告消息焊唬。在本案例中,我們使用數(shù)值2
表示我們只關(guān)注錯誤消息看靠。這樣你在輸出結(jié)果中就不會看到腳本執(zhí)行的開始和結(jié)束時間這樣的信息性消息赶促。
測試并響應(yīng)特定錯誤消息
所有的錯誤和警告都會生成一個特定的錯誤代碼。我們可以在腳本中來檢查特定的錯誤代碼挟炬,并基于這些錯誤代碼來執(zhí)行特定的操作鸥滨。
Getting ready
地理處理工具的返回的錯誤和警告都包含一個六位數(shù)字代碼和一條描述性信息。你在腳本中可以檢測特定的錯誤代碼并作出相應(yīng)地反饋谤祖。你可以在ArcGIS幫助系統(tǒng)中的地理處理|工具錯誤和警告(Geoprocessing|Tool errors and warnings)中看到包含所有錯誤消息和代碼的列表婿滓。如下圖所示,所有的錯誤根據(jù)錯誤代碼都有一個對應(yīng)的描述頁面:
How to do it...
按照以下步驟來學(xué)習(xí)如何編寫代碼來響應(yīng)地理處理工具執(zhí)行過程中生成的特定的錯誤代碼:
1.點擊開始|所有程序|ArcGIS|ArcGIS Desktop 10幫助
(Start|Programs|ArcGIS|ArcGIS for Desktop Help)打開幫助系統(tǒng)粥喜。
2.找到地理處理|工具錯誤和警告|工具錯誤1-10000|工具錯誤和警告:701-800(Geoprocessing|Tool errors and warnings|Tool errors 1-10000|Tool errors and warning:701-800)凸主。
3.選擇000735:<值>:需要值(000735:<value>:value is required)。該錯誤提示沒有提供工具需要的必選參數(shù)额湘。我們在腳本中沒有提供緩沖距離參數(shù)導(dǎo)致了錯誤消息產(chǎn)生卿吐,其中包括了我們在幫助系統(tǒng)中看到的錯誤代碼(000735)旁舰。下面的消息代碼中,你會發(fā)現(xiàn)完整的錯誤消息文本但两。留意錯誤代碼(000735)鬓梅。
ERROR000735:Distance[value or field]:Value is required
4.在IDLE中打開C:\ArcpyBook\Ch12\ErrorHandling.py
文件。
5.如下所示修改腳本代碼:
except:
print "Error found in Buffer tool \n"
errCode = arcpy.GetReturnCode(3)
if "735" in str(errCode):
print "Distance value not provided \n"
print "Running the buffer again with a default value \n"
defaultDistance = "100 Feet"
arcpy.Buffer_analysis("Steams.shp","Streams_Buff.shp",defaultDistance)
print "Buffer complete"
6.保存并運行代碼谨湘。你會看到如下消息:
Error found in Buffer tool
Distance value not provided for buffer
Running the buffer again with a default distance value
Buffer complete
How it works...
我們在代碼中調(diào)用了arcpy.GetReturnCode()
函數(shù)來返回工具生成的錯誤代碼绽快。之后if
語句用來檢測錯誤代碼中是否包含數(shù)值735
,該代碼表示錯誤是由于沒有提供工具必選參數(shù)造成紧阔。接下來我們提供了一個緩沖距離值并再次調(diào)用Buffer
工具坊罢。
調(diào)用GetMessage()函數(shù)返回單個消息
GetMessages()
會返回上一次工具運行時生成的全部消息列表,不過你可以調(diào)用GetMessage()
函數(shù)來獲取其中的單個消息擅耽。
Getting ready
到目前為止活孩,我們都是返回工具生成的全部消息。不過乖仇,你可以調(diào)用GetMessage()
函數(shù)為用戶返回單個消息憾儒,該函數(shù)接受一個整型參數(shù)來指定要返回的特定消息。工具生成的消息都是位于消息列表或數(shù)組中乃沙。
這里提醒一下起趾,列表是零值開始計算索引值的,也就意味著了列表中的第一個元素的位置為0
警儒。比如训裆,GetMessage(0)
會返回列表中的第一條信息,而GetMessage(1)
則返回第二條信息蜀铲。第一條消息通常是當(dāng)前運行的工具名稱以及參數(shù)信息边琉。第二條消息返回腳本運行的開始時間,而最后一條消息則返回腳本的結(jié)束時間记劝。
How to do it...
1.在IDLE中打開C:\ArcpyBook\Ch12\ErrorHandling.py
文件变姨。
2.如下所示修改代碼:
import arcpy
try:
arcpy.env.workspace = "C:/ArcpyBook/data"
arcpy.Buffer_analysis("Streams.shp","Streams_Buff.shp")
except:
print arcpy.GetMessage(1)
print arcpy.GetMessage(arcpy.GetMessageCount()-1)
3.保存并運行腳本,你會看到如下結(jié)果顯示:
Start Time: Wed Nov 14 09:07:35 2012
Failed at Wed Nov 14 09:07:35 2012 (Elapsed Time: 0.00 seconds)
How it works...
我們之前沒有介紹GetMessageCount()
函數(shù)厌丑。該函數(shù)返回工具生成的消息數(shù)量钳恕。記住消息列表是從零值開始索引,因此我們需要從GetMessageCount()
返回的結(jié)果中減去1來獲取列表中的最后一條消息蹄衷。否則的話,我們就是在試圖訪問列表中不存在的消息厘肮。在本案例中愧口,我們獲取了腳本執(zhí)行的開始和結(jié)束時間。第二條消息通常是腳本執(zhí)行的開始時間类茂,而最后一條消息則是腳本執(zhí)行的結(jié)束時間耍属。下面的返回結(jié)果中則說明了這個問題:
Message 0 - Executing: Buffer c:/ArcpyBook/data\Streams.shp c:/ArcpyBook/ data\Streams_Buff.shp # FULL ROUND NONE #
Message 1 - Start Time: Tue Nov 13 22:23:04 2012
Message 2 - Failed to execute. Parameters are not valid.
Message 3 - ERROR 000735: Distance [value or field]: Value is required
Message 4 - Failed to execute (Buffer).
Message 5 - Failed at Tue Nov 13 22:23:04 2012 (Elapsed Time: 0.00 seconds)
全部消息的數(shù)量為6
托嚣,但是最后一條消息對應(yīng)的索引數(shù)為5
。這也就是為什么我們要在腳本代碼中減去1
的緣故厚骗。本案例中示启,由于腳本中發(fā)生錯誤,因此開始和結(jié)束時間相同领舰。盡管如此夫嗓,該案例仍然說明了如何來獲取由工具生成的單個消息。