1. 程式人生 > >Python3基礎(九) 錯誤和異常

Python3基礎(九) 錯誤和異常

本文主要介紹Python中的錯誤和異常,涉及到簡單的異常處理、丟擲異常以及清理動作。至於自定義異常類,將在介紹類與繼承的時候講到。

一、定義

常見的兩種錯誤:語法錯誤異常

1、語法錯誤(Syntax Errors)

語法錯誤,也就是解析時錯誤。當我們寫出不符合python語法的程式碼時,在解析時會報SyntaxError,並且會顯示出錯的那一行,並用小箭頭指明最早探測到錯誤的位置。比如:

x = input('please input an integer:')
if int(x) > 5:
    print 'hello world'
在python 3中會報語法錯誤:
File "/home/songlee/test", line 3
  print 'hello world'
                    ^
SyntaxError: invalid syntax

2、異常(Exceptions)

即使語句或表示式在語法上是正確的,但在嘗試執行時也可能發生錯誤,執行時錯誤就叫做 異常(Exceptions) 。異常並不是致命的問題,因為我們可以在程式中對異常進行處理。

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

>>> 2 + x*3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly

上面展示了三種exception的型別:ZeroDivisionError、NameError、TypeError ,它們都是內建異常的名稱。標準異常的名字是內建的識別符號 (但並不是關鍵字)。


二、處理異常(try…except…)

我們可以使用 try…except… 語句來處理異常。try 語句塊中是要執行的語句,except 語句塊中是異常處理語句。一個 try 語句可以有多條的 except 語句,用以指定不同的異常,但至多隻有一個會被執行:

try:
    x = int(input('please input an integer:'))
    if 30/x > 5:
        print('Hello World!')
except ValueError:
    print('That was no valid number. Try again...')
except ZeroDivisionError:
    print('The divisor can not be zero, Try again...')
except:
    print('Handling other exceptions...')

上面這段程式碼,當輸入a(非數字)時,將丟擲ValueError異常;當輸入0時,將丟擲ZeroDivisionError異常;當丟擲其他型別的異常時,將執行except:後的處理語句。

如果在 try 語句執行時,出現了一個異常,該語句的剩下部分將被跳過。並且如果該異常的型別匹配到了 except 後面的異常名,那麼該 except 後的語句將被執行。注意,如果 except 後面沒有跟異常名,表示它匹配任何型別的異常,except:必須放在最後。

一個 except 語句可以同時包括多個異常名,但需要用括號括起來,比如:

except (RuntimeError, TypeError, NameError):
    pass
try...except...語句可以有一個可選的 else 語句。else 語句必須要放在所有 except 語句後面,當沒有異常發生的時候,else 從句將被執行:
try:
    name = input('please input an integer:')
    f = open(name, 'r')
except IOError:
    print('Cannot open', name)
except:
    print('Unexpected errors.')
else:
    print('close the file', name)
    f.close()

三、丟擲異常(raise)

raise 語句允許程式設計師強制地丟擲一個特定的異常,例如:

>>> raise NameError('HiThere')     # 丟擲異常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: HiThere

raise 丟擲的異常必須是一個異常例項或類(派生自 Exception 的類)。


四、清理動作(finally)

try 語句有另一種可選的finally從句,用於自定義一些掃尾清理的工作。

try:
    x = int(input('please input an integer:'))
    if x > 5:
        print('Hello World!')
except ValueError:
    print('It was not a number. Try again.')
finally:
    print('Some clean-up actions!')
與 else 從句的區別在於: else 語句只在沒有異常發生的情況下執行,而 finally 語句則不管異常發生與否都會執行。準確的說,finally 語句總是在退出 try 語句前被執行,無論是正常退出、異常退出,還是通過break、continue、return退出。
>>> def divide(x, y):
...     try:
...             result = x / y
...     except ZeroDivisionError:
...             print('error: division by zero!')
...     else:
...             print('executing else-clause,', 'result is', result)
...     finally:
...             print('executing finally-clause')
... 

>>> divide(2, 1)      # 正常退出
executing else-clause, result is 2.0
executing finally-clause

>>> divide(2, 0)      # 異常退出
error: division by zero!
executing finally-clause

>>> divide('2', '1')  # 異常退出,異常未被處理。
executing finally-clause
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

從上面看出,finally 語句在任何情況下都被執行了。對於沒有被 except 處理的異常,將在執行完 finally 後被重新丟擲。

另外,有些物件預定義了標準的清理動作(clean-up actions)。當物件不再需要時,該動作將被執行,無論對其使用的操作是否成功。例如下面的檔案I/O例子:

for line in open("myfile.txt"):
    print(line, end="")
這段程式碼的問題在於,在此程式碼成功執行後,檔案依然被開啟著。但with語句可以讓檔案物件在使用後被正常的清理掉:
with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

在執行該語句後,檔案 f 就會被關閉,就算是在讀取時碰到了問題,檔案 f 也會被關閉。像檔案這樣的物件,總會提供預定義的清理工作。

相關推薦

Python3基礎 錯誤異常

本文主要介紹Python中的錯誤和異常,涉及到簡單的異常處理、丟擲異常以及清理動作。至於自定義異常類,將在介紹類與繼承的時候講到。 一、定義 常見的兩種錯誤:語法錯誤 和 異常。 1、語法錯誤(Syntax Errors) 語法錯誤,也就是解析時錯誤。當我們寫出不符合pyt

從零開始學習PYTHON3講義字典型別插入排序

《從零開始PYTHON3》第九講 第六講、上一講我們都介紹了列表型別。列表型別是程式設計中最常用的一種型別,但也有挺明顯的缺陷,比如: data = [5,22,34,12,87,67,3,43,56,23] 還記得讓程式更友好的概念嗎?上一條語句所定義的列表,我們沒辦法很容易的知道這些值代表什麼

Java基礎:logback實現日誌按天大小切分

【前言】        專案中每天會列印很多日誌,有時候進行排錯開啟一個大的日誌檔案(我們有一個系統的線上日誌檔案大小已經超過20G)是一件很可怕的事情;對日誌進行按天的切分是一件非常有必要的事情。 【日誌按天切分】          一、在application.pr

redis使用基礎 ——Redis虛擬內存

兩個 數據 規則 導致 文件中 寫入 ron 開始 路徑 redis使用基礎(九) ——Redis虛擬內存 (轉載請附上本文鏈接——linhxx) 一、概述 Redis的數據是保存在內存中,當物理內存不足,其會保存在虛擬內存(VM)中。Redis的

自興人工智能------------python入門基礎2列表元祖

div 最小值 最大值 布爾 str 列操作 一段 ext .so 一.通用序列操作: 列表中所有序列都可以進行特定的操作,包括索引(indexing).分片(slicing).序列相加(adding).乘法,成員資格,長度,最小值,最大值,下面會一一介紹這些操作法。 1.

並發基礎 java線程的終止與中斷

建議 暫停 boolean read 便是 -m java sin 修飾符 1、簡單了解一下:為何不贊成使用 Thread.stop、Thread.suspend 和 Thread.resume? ??suspend 、resume、stop方法分別完成了線程的暫停、恢復、

Python3爬蟲 數據存儲之關系型數據庫MySQL

如果 except ror 故障 cit -c sqlit 鏈接庫 port Infi-chu: http://www.cnblogs.com/Infi-chu/ 關系型數據庫關系型數據庫是基於關系模型的數據庫,而關系模型是通過二維表來保存的,所以關系型數據庫的存儲方式就

Java基礎面試題

面試題 io流 多線程 面試題:字節緩沖輸出流它的構造方法為什麽不能直接傳遞路徑/文件? 緩沖輸入流/緩沖輸出流,它只是在底層內部提供一個緩沖區的數組, 底層實現文件的復制/讀取/寫入這些操作都依賴於基本流對象來操作(InputStream/OutputStream/FileInputStrea

JAVA基礎13---順序選擇控制語句

 流程控制 Java中的流程控制有三類:順序控制、選擇控制和迴圈控制 順序控制語句        在Java中的程式的執行流程:         &nbs

Python語言程式設計基礎7—— 檔案資料格式化

返回字串 file = input() #返回字串 fo = open(file,"r").read(6) print(fo)   返回列表形式 file = input() fo = open(file,"r") #print(fo) #返回列表形式 pr

JAVA基礎34---StringBufferStringBuilder

StringBuffer / StringBuilder 為了解決的問題:String是不可變的造成的記憶體浪費和String物件的使用效率比較低這兩個問題 StringBuffer:執行緒安全的可變字元序列,通過某些方法呼叫可以改變該序列的長度和內容。 StringBuilder

Java中io流的學習ByteArrayInputStreamByteArrayOutputStream

ByteArrayInputStream(記憶體輸入流)繼承於InputStream,ByteArrayOutputStream(記憶體輸出流)繼承於OutputStream。記憶體流是關不掉的,一般用來存放一些臨時性的資料,理論值是記憶體大小。 常用的方法是:read(),一系列read方法,

java基礎繼承

關鍵字: extends 為什麼存在: 多個類存在相同屬性和行為,將其放在一個父類中,其餘的類只需要繼承就行。提高程式碼複用性 格式: class 子類名 extends 父類名{} eg: Person類: public class Person

Go語言基礎—— Go語言結構體、Go語言切片Slice、range遍歷、Go語言Map集合

Go語言結構體 Go 語言中陣列可以儲存同一型別的資料,但在結構體中我們可以為不同項定義不同的資料型別。 結構體是由一系列具有相同型別或不同型別的資料構成的資料集合。  結構體表示一項記錄,比如儲存圖書館的書籍記錄,每本書有以下屬性: Title :標題&nbs

JAVA高階基礎6---VectorLinkedList

Vector 是 List 介面一個長度可變的陣列的實現。 可以儲存null  是同步的(是執行緒安全的) 注:更多詳細方法請自行在 API 上查詢  ArrayList和Vector的區別:是否是同步的 package or

微信小遊戲-CocosCreator 基礎

Label : Line Heght :每行高度 Node的H :整體高度 OverFlow:None 一行 CLAMP :改變Node的w 改變寬度 ,只有一行 SHRINK :根據Node的w和h

python之Linux基礎

軟體安裝與解除安裝更新Ubuntu軟體下載地址 尋找國內映象源所謂的映象源:可以理解為提供下載軟體的地⽅,⽐如Android⼿機上可以下載軟體的91 ⼿機助⼿;iOS⼿機上可以下載軟體的AppStore 備份Ubuntu預設的源地址sudo cp /etc/apt/sources.list /etc

QT基礎訊號

什麼是訊號和槽?訊號和槽的作用 訊號和槽都是函式,比如按下視窗上的一個按鈕後想要彈出一個對話方塊,那麼就可以將這個按鈕的單擊訊號和我們定義的槽關聯起來,在這個槽中可以建立一個對話方塊,並且顯示它。這樣,當單擊這個按鈕時就會發射訊號,進而執行我們的槽來顯示一個對

http協議基礎請求響應報文的構成

http協議用於客戶端和伺服器之間的通訊,請求訪問資源的一方稱為客戶端,而提供資源響應的一方稱為伺服器端。 下面就是客戶端和服務端之間簡單的通訊過程 PS:請求必須從客戶端建立通訊,服務端沒收到請求之前不會發送響應 下面先來說說請求的構成: 1)請求方法URI協議/版本  2)請求頭(