Python全攻略:第八節 - Error Handling and Exceptions (118-124)

錯誤處理與例外教學筆記


常見問題與答案形式教學

1. 什麼是 Guard Clauses(保護條款)?

Guard Clauses 是一種程式設計模式,用來避免多層巢狀的 if 條件式。

範例 1:使用 Guard Clauses 的程式碼

# 使用 Guard Clauses
def function():
    if A:
        do_A()
        if B:
            do_B()
            if C:
                do_C()

上述程式碼的每一層都使用條件來保護程式的執行。如果條件不成立,就不會繼續執行。


2. 如何使用例外處理來簡化程式碼?

可以透過例外處理(Exception Handling)來簡化程式碼,使其更具可讀性。

範例 2:使用 Exception Handling 的程式碼

# 使用 Exception Handling
def function():
    if not A:
        raise Exception("A is not valid")
    do_A()

    if not B:
        raise Exception("B is not valid")
    do_B()

這樣的寫法避免了過多的巢狀結構,使程式碼更易讀。


3. Guard Clauses 與 Exception Handling 的差異?

範例比較:

使用 Guard Clauses:

# Guard Clauses
def divide(a, b):
    if isinstance(a, int) and isinstance(b, int):
        if b != 0:
            return a / b
        else:
            return "The 2nd argument cannot be zero."
    else:
        return "Invalid argument type!"

print(divide(10, "h"))  # Invalid argument type!
print(divide(10, 0))     # The 2nd argument cannot be zero.
print(divide(10, 2))     # 5.0

使用 Exception Handling:

# Exception Handling
def divide(a, b):
    if not isinstance(a, int) or not isinstance(b, int):
        raise ValueError("Not valid type given!")

    if b == 0:
        raise ZeroDivisionError("The 2nd argument cannot be zero.")

    return a / b

try:
    print(divide(10, "h"))
except Exception as e:
    print(e)  # Not valid type given!

try:
    print(divide(10, 0))
except Exception as e:
    print(e)  # The 2nd argument cannot be zero.

try:
    print(divide(10, 2))
except Exception as e:
    print(e)  # 5.0

4. 什麼是 Context Manager?

Context Manager 是用來管理資源的工具,例如自動開啟和關閉檔案。

傳統做法(未使用 Context Manager):

try:
    file = open("hello.txt")
    data = file.read()
    file.close()
except FileNotFoundError:
    print("File not found...")

使用 Context Manager 的做法:

try:
    with open("hello.txt") as file:
        data = file.read()  # 不需手動關閉檔案
except FileNotFoundError:
    print("File not found...")

優點:

  • 不需手動關閉資源
  • 減少資源洩漏的風險

5. 什麼是 Pylint?

Pylint 是一個用來分析 Python 程式碼的工具,可以幫助檢查錯誤和程式碼風格。

範例 1:未修正的程式碼

# try.py
a = 1
b = 2
print(a)
print(B)

Pylint 的輸出:

************* Module try
try.py:1:0: C0114: Missing module docstring (missing-module-docstring)
try.py:1:0: C0103: Constant name "a" doesn't conform to UPPER_CASE naming style (invalid-name)
try.py:2:0: C0103: Constant name "b" doesn't conform to UPPER_CASE naming style (invalid-name)
try.py:4:6: E0602: Undefined variable 'B' (undefined-variable)

範例 2:修正後的程式碼

'''Testing...'''
A = 1
B = 2
print(A)
print(B)

Pylint 的輸出:

Your code has been rated at 10.00/10 (previous run: 0.00/10, +10.00)

6. 什麼是 Unit Testing?

Unit Testing 是一種測試方法,用來測試程式的個別功能是否正常運作。Python 的標準函式庫包含 unittest

範例:

# cap.py
def cap_test(text):
    return text.capitalize()
# main_program.py
import unittest
import cap

class MyTest(unittest.TestCase):
    def test_one(self):
        text = "sample"
        result = cap.cap_test(text)
        self.assertEqual(result, "Sample")

    def test_two(self):
        text = "just testing..."
        result = cap.cap_test(text)
        self.assertEqual(result, "Just Testing...")

if __name__ == "__main__":
    unittest.main()

輸出結果:

.F
======================================================================
FAIL: test_two (__main__.MyTest.test_two)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "main_program.py", line 14, in test_two
    self.assertEqual(result, "Just Testing...")
AssertionError: 'Just testing...' != 'Just Testing...'
- Just testing...
?      ^
+ Just Testing...
?      ^
----------------------------------------------------------------------
Ran 2 tests in 0.003s

FAILED (failures=1)

修正後的程式碼:

# 修改後的 cap.py
def cap_test(text):
    return text.title()

輸出結果:

..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
1個讚