Python 3 學習筆記之——錯誤和異常
1. 語法錯誤
Python 的語法錯誤被稱為解析錯,語法分析器會指出出錯的代碼行,並且在最先找到的錯誤的位置標記一個小小的箭頭。
>>> while True
File "<stdin>", line 1
while True
^
SyntaxError: invalid syntax
2. 異常
即使 Python 程序的語法是正確的,但是在運行的時候,也有可能發生錯誤,運行期監測到的錯誤稱為異常。
>>> print(name) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name ‘name‘ is not defined >>> a = [1, 2, 3] >>> b = a(0) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: ‘list‘ object is not callable >>> 10 / 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero
3. 異常處理
try 語句按照以下方式工作:
- 首先,執行 try 子句,也就是在 try 和 except 之間的語句
- 如果沒有異常發生,忽略 except 子句,程序繼續運行
- 如果在 try 子句執行過程中發生了異常,那麽 try 子句余下的部分將被忽略
- 若異常的類型和 except 之後的名稱相符,那麽對應的 except 子句將被執行,然後再執行 try 語句之後的代碼
- 若異常沒有與任何的 except 匹配,那麽這個異常將會傳遞到上層的 try 中去
while True: try: x = int(input("Please enter a number: ")) break except ValueError: print("Oops! That was no valid number. Try again!") Please enter a number: we Oops! That was no valid number. Try again! Please enter a number: sd Oops! That was no valid number. Try again! Please enter a number: 23
在上面的例子中,我們讓用戶通過鍵盤來輸入一個合法的整數。如果輸入的是字符串,那 int 函數就無法將字符串轉為整數,程序就會拋出一個異常,然後執行 except 子句,打印信息提示我們重新輸入,直到輸入一個整數程序 break 結束。
一個 except 子句可以同時處理多個異常,這些異常被放在一個括號裏成為一個元組。
except (RuntimeError, TypeError, NameError):
pass
最後一個 except 子句可以忽略異常的名稱,它將被當做通配符使用。此時可以打印出錯誤信息,然後再次把異常拋出。
import sys try: f = open(‘test.txt‘) s = f.readline() i = int(s.strip()) except OSError as err: print("OS error: {0}".format(err)) except ValueError: print("Could not convert data to an integer.") except: print("Unexpected error:", sys.exc_info()[0]) raise # 沒有相應文件時報錯 OS error: [Errno 2] No such file or directory: ‘test.txt‘ # 文件中第一行為字符串無法轉化為整數時報錯 Could not convert data to an integer.
try except 語句還有一個可選的 else 子句,如果使用這個子句,那麽必須放在所有的 except 子句之後。這個子句將在try子句沒有發生任何異常的時候執行。
import sys
try:
f = open(‘test.txt‘)
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
else:
print(i)
# 1
使用 else 子句比把所有語句都放在 try 子句裏面要好,這樣可以避免一些意想不到的而 except 又沒有捕獲到的異常。
異常處理也可以處理子句中調用函數甚至是間接調用函數裏拋出的異常。
3. 用戶自定義異常
我們可以通過創建一個新的異常類來擁有自己的異常。異常類繼承自 Exception,可以直接繼承,或者間接繼承。
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
try:
raise MyError(2*2)
except MyError as e:
print(‘My exception occurred, value:‘, e.value)
# My exception occurred, value: 4
4. 定義清理行為
try 語句還有另外一個可選的子句 finally,它定義了無論任何情況下都會執行的清理行為。
def divide(x, y):
try:
result = x / y
except ZeroDivisionError:
print("division by zero!")
else:
print("result is", result)
finally:
print("executing finally clause")
divide(2, 1)
result is 2.0
executing finally clause
divide(2, 0)
division by zero!
executing finally clause
divide(‘2‘, ‘1‘)
executing finally clause
TypeError Traceback (most recent call last)
<ipython-input-19-0fe65f250ff1> in <module>()
----> 1 divide(‘2‘, ‘1‘)
<ipython-input-16-fb375c737bea> in divide(x, y)
1 def divide(x, y):
2 try:
----> 3 result = x / y
4 except ZeroDivisionError:
5 print("division by zero!")
TypeError: unsupported operand type(s) for /: ‘str‘ and ‘str‘
一些對象定義了標準的清理行為,當程序中不需要它的時候,那麽這個標準行為就會執行。關鍵詞 with 語句可以保證諸如文件之類的對象在使用完之後一定會正確=地執行清理行為。
參考資料 菜鳥教程
獲取更多精彩,請關註「seniusen」!
Python 3 學習筆記之——錯誤和異常