---
# System prepended metadata

title: Python學習筆記

---

---
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!
:::


