--- title: 'Python學習筆記' disqus: hackmd --- Python 學習筆記之路 Part.4 = > 上一回(第三回 下)記錄了文件處理 > [Python學習筆記之路 第一回](/fLF0QqeaT3CLKU0Onr-Q3Q) > [Python學習筆之路 第二回](/wVM476iMRIqXglr77AA61g) > [Python學習筆記之路 第三回(上)](/SBQVlHk7T9iCGe_qbM3zWg) > [Python學習筆記 第三回(下)](/Z5Ds9Qd6SyuKetVkwBl0lw) > 此回進入新回數,查找錯誤 目錄 == [TOC] Bug (取自維基百科) == ### Bug的意義 程式錯誤(英語:Bug),是程式設計術語,是指軟體執行時因程式本身有錯誤而造成功能不正常、當機、資料遺失、非正常中斷等現象。有些程式錯誤會造成電腦安全隱患,此時叫漏洞。 一些有趣的錯誤有時也會成為一種樂趣。在電腦遊戲中,假如一些錯誤不令遊戲出現大錯誤的話,經常會變成一種玩遊戲時的秘技(秘技有時是遊戲設計者故意加入,用於檢查程式設計,繞過不需要的步驟直接檢驗需要的地方時所使用的代碼)。 有嚴重後果的錯誤會受到廣泛關注。修補、改正軟體程式錯誤的過程稱為除錯。 ### 最被熟知的"Bug"一詞由來 1947年9月9日,葛麗絲·霍普(Grace Hopper)發現了第一個電腦bug。有一次Mark II突然宕機,整隊團隊都搞不清電腦為何不能正常運作。經過大家深度挖掘,發現原來有飛蛾意外飛入一臺電腦引起故障(如圖所示)。團隊很快排除錯誤,並在日誌本記錄這事。也因此,人們逐漸開始用「Bug」(原意「蟲子」)來稱呼電腦錯誤。現在在華盛頓美國國家歷史博物館還可以看到這份遺稿。 ![First_Computer_Bug,_1945](https://hackmd.io/_uploads/SkLAyNs46.jpg) Python中如何實現與其意義? == **抓捕bug的作用是:** 提前假設某處可能會出現的異常, 做好提前準備,若真的出現異常, 就可以有後續手段 #### **基本語法:** # try: # 可能出現的error代碼 # except: # 真的出現異常的執行代碼 假設你的D槽不存在abc.txt這個文字檔,當try了發現出錯找不到了,便會執行except裡面的程式碼,首先會先print訊息,接著在D槽新增了一個名叫abc.txt的文件,並且是用write模式寫入。 ```gherkin= try : f = open("D:/abc.txt", "r") except: print("文件出現異常, 因為文件不存在, 我將open模式, 改為w模式進行") f = open("D:/abc.txt", "w") ``` #### 抓捕指定Bug: 一般try下方只放一行嘗試執行的code **語法:** # try: # print(name) # except NameError as e: # print('name 變數名稱為定義錯誤') ```gherkin= try: print(whatTheHell) except NameError as e: # 將bug取名 print("出現變數未定義的異常") print(e) # 將bug存放在e裏頭 ``` #### 捕獲複數個bug **語法:** # try: # print(name) # except(NameError, ZeroDivisionError): # print('...') 這裡是try已經抓到了1/0的錯誤,所以直接執行了except的程式碼,並且利用print方式將該錯誤印出;也就是若將print(name)先放上,那就錯誤訊息將會print出name is not defined. ```gherkin= try: 1/0 print(name) except(NameError, ZeroDivisionError) as e: print(f"出現了為定義 或者 除以0的異常錯誤{e}") ``` #### 捕捉所有異常 在此段程式碼中,只要出現錯誤都會被儲存在e變數,可以利用print形式將其印出,你會發現跟上一段程式碼,我將1/0移到後頭,所以他先偵測到了mdfoighjndif變數不存在,所以直接進入except的程式碼。 ```gherkin= try: print(mdfoighjndif) 1/0 except Exception as e: print("出現異常") print(e) ``` #### else應用 若你希望在出現錯誤時列出錯誤,並且在正確時讓你知道程式碼正確,可以使用else函數進行 **基本語法:** # try: # print(1) # except Exception as e: # print(e) # else: # print("我是 else, 目前沒有發生任何異常") 假設我在D槽沒有test.txt文件,那將會出現"we finding error";若我在D槽新增了一個test.txt文件,將會出現"我是 else, 目前沒有發生任何異常" ```gherkin= try : f = open("D:/test.txt", "r") except Exception as e : print("we finding error") else : print("我是 else, 目前沒有發生任何異常") ``` #### try函數中特殊變數 finally 當你不管三七二十一,我就是要執行程式碼不管有沒有錯誤,在try裡面可以用finally函數。 **基本語法:** # try: # print(1) # except Exception as e: # print(e) # else: # print("我是 else, 目前沒有發生任何異常") # finally: # f.close() 此段程式碼中,我的D槽沒有te.txt函數,所以進入except函數中,印出並且創建了一個新的te.txt函數,通常應該在這裡就會停止,但我們引入了finally函數,不論有沒有出現錯誤,我最終都會執行finally裡面函數。 ```gherkin= try : f = open("D:/te.txt", "r") except Exception as e : print("we finding error") f = open("D:/te.txt", "w") else : print("我是 else, 目前沒有發生任何異常") finally: print("我是finally, 有沒有異常我都要執行") f.close() ``` #### 錯誤具有傳遞性質 有時候我們會定義許多不同的函數,在之後的函數進行引用與彙總,若你每次都要去底層(一開始的函數)去找錯誤,那便會變得很麻煩,也失去Python的便利性質。 所以在Python中,我們讓錯誤具有傳遞的性質,他會從底層一路繼承到最後套用的函數,所以我們只要在頂層catch,並切在最後用exception接收就可以知道是哪裡出了問題。 在此例子中,function 1中執行了錯誤的數學算式,接著用function 2去引用,接著main()函數再用了function 2進行try。 可以發現他先從function2開始運行,發現function2沒有錯,接著去看function1,ㄟ,發現錯誤了,所以用e這個變數去接收,最後print出來就可以看到啦! ```gherkin= def func1(): print("fun1開始執行") num = 1/0 print("func1 結束執行") def func2(): print("func2 開始執行") func1() print("func2 結束執行") def main(): try: func2() except Exception as e: print(f"出現異常了, 異常的訊息是:{e}") main() ``` 執行結果 >func2 開始執行 fun1開始執行 出現異常了, 異常的訊息是:division by zero 結語 == 此回筆記記錄了如何在有預期的方式處理ERROR,這在許多函數裡面都非常實用,當你的用 戶輸入錯誤,不論是語法或是含是內部無法執行,都可以很好的判斷並且給出錯誤點。 :::info **Find this document incomplete?** Leave a comment! :::