1. 程式人生 > >Python3簡明教程之8錯誤和異常

Python3簡明教程之8錯誤和異常

Python3之錯誤和異常

作為Python初學者,在剛學習Python程式設計時,經常會看到一些報錯資訊,在前面我們沒有提及,這章節我們會專門介紹。

Python有兩種錯誤很容易辨認:語法錯誤和異常。

語法錯誤

Python 的語法錯誤或者稱之為解析錯,是初學者經常碰到的,如下例項

>>> while True print('Hello world')

  File "<stdin>", line 1, in ?

    while True print('Hello world')

                   ^

SyntaxError: invalid syntax

這個例子中,函式 print() 被檢查到有錯誤,是它前面缺少了一個冒號(:)。

語法分析器指出了出錯的一行,並且在最先找到的錯誤的位置標記了一個小小的箭頭。

異常

即便Python程式的語法是正確的,在執行它的時候,也有可能發生錯誤。執行期檢測到的錯誤被稱為異常。

大多數的異常都不會被程式處理,都以錯誤資訊的形式展現在這裡:

>>> 10 * (1/0)

Traceback (most recent call last):

  File "<stdin>", line 1, in ?

ZeroDivisionError: division by zero

錯誤處理

try機制

在程式執行的過程中,

如果發生了錯誤,可以事先約定返回一個錯誤程式碼

這樣,就可以知道是否有錯,以及出錯的原因。

但是,用錯誤碼來表示是否出錯十分不便,

因為函式本身應該返回的正常結果和錯誤碼混在一起,

造成呼叫者必須用大量的程式碼來判斷是否出錯

一旦出錯,還要一級一級上報,

直到某個函式可以處理該錯誤,十分麻煩。

所以高階語言通常都內建了一套try...except...finally...

的錯誤處理機制,Python也不例外。

一個例子來看看try的機制:

try:

    print('try...')

    r = 10 / 0

    print('result:', r)

except ZeroDivisionError as e:

    print('except:', e)

finally:

    print('finally...')

print('END')

當我們認為某些程式碼可能會出錯時,

就可以用try來執行這段程式碼,

如果執行出錯,則後續程式碼不會繼續執行,

而是直接跳轉至錯誤處理程式碼,

except語句塊,執行完except後,

如果有finally語句塊,則執行finally語句塊,

至此,執行完畢。

except語句塊

上面的程式碼在計算10 / 0時會產生一個除法運算錯誤:

try...

except: division by zero

finally...

END

從輸出可以看到,

當錯誤發生時,後續語句print('result:', r)不會被執行,

except由於捕獲到ZeroDivisionError,因此被執行。

最後,finally語句被執行。然後,程式繼續按照流程往下走。

finally語句塊

如果把除數0改成2,則執行結果如下:

try...

result: 5

finally...

END

由於沒有錯誤發生,所以except語句塊不會被執行

但是finally如果存在,則一定會被執行

多個except

通常,錯誤應該有很多種類,

針對不同型別的錯誤,應該由不同的except語句塊處理:

try:

    print('try...')

    r = 10 / int('a')

    print('result:', r)

except ValueError as e:

    print('ValueError:', e)

except ZeroDivisionError as e:

    print('ZeroDivisionError:', e)

finally:

    print('finally...')

print('END')

int()函式可能會丟擲ValueError,

所以用一個except捕獲ValueError,

用另一個except捕獲ZeroDivisionError。

else語句塊

此外,如果沒有錯誤發生,

可以在except語句塊後面加一個else,

當沒有錯誤發生時,會自動執行else語句:

try:

    print('try...')

    r = 10 / int('2')

    print('result:', r)

except ValueError as e:

    print('ValueError:', e)

except ZeroDivisionError as e:

    print('ZeroDivisionError:', e)

else:

    print('no error!')

finally:

    print('finally...')

print('END')

異常呼叫棧

如果錯誤沒有被捕獲,它就會一直往上拋

最後被Python直譯器捕獲,列印一個錯誤資訊,然後程式退出。

使用try...except捕獲錯誤還有一個巨大的好處:

就是可以跨越多層呼叫,比如函式main()呼叫a(),a()呼叫b(),

結果b()出錯了,這時,只要main()捕獲到了,就可以處理。

也就是說,不需要在每個可能出錯的地方去捕獲錯誤

只要在合適的層次去捕獲錯誤就可以了。

這樣一來,就大大減少了寫try...except...finally的麻煩。

除錯

程式能一次寫完並正常執行的概率很小,基本不超過1%。

總會有各種各樣的bug需要修正。

有的bug很簡單,看看錯誤資訊就知道,

有的bug很複雜,我們需要知道出錯時,哪些變數的值是正確的,

哪些變數的值是錯誤的,

因此,需要一整套除錯程式的手段來修復bug

除錯方法之print

第一種方法簡單直接粗暴有效,

就是用print()把可能有問題的變數打印出來看看:

def foo(s):

    n = int(s)

    print('>>> n = %d' % n)

    return 10 / n

def main():

    foo('0')

main()

執行後在輸出中查詢列印的變數值

用print()最大的壞處是將來還得刪掉它,

程式裡到處都是print(),

執行結果也會包含很多垃圾資訊。

除錯方法之assert

凡是用print()來輔助檢視的地方,

都可以用斷言(assert)來替代:

def foo(s):

    n = int(s)

    assert n != 0, 'n is zero!'

    return 10 / n

def main():

    foo('0')

assert的意思是,表示式n != 0應該是True,

否則,根據程式執行的邏輯,後面的程式碼肯定會出錯。

如果斷言失敗,assert語句本身就會丟擲AssertionError:

AssertionError: n is zero!

程式中如果到處充斥著assert,和print()相比也好不到哪去。

不過,啟動Python直譯器時可以用-O引數來關閉assert:

關閉後,你可以把所有的assert語句當成pass來看。

除錯方法之logging

把print()替換為logging是第3種方式,

和assert比,logging不會丟擲錯誤,而且可以輸出到檔案

import logging

logging.basicConfig(level=logging.INFO)

s = '0'

n = int(s)

logging.info('n = %d' % n)

print(10 / n)

logging.info()就可以輸出一段文字。

它允許指定記錄資訊的級別,有debug,info,warning,error等幾個級別,

當我們指定level=INFO時,logging.debug就不起作用了。

同理,指定level=WARNING後,debug和info就不起作用了。

這樣一來,可以放心地輸出不同級別的資訊,也不用刪除

pdb

第4種方式是啟動Python的偵錯程式pdb,

讓程式以單步方式執行,可以隨時檢視執行狀態。

我們先準備好程式:

# err.py

s = '0'

n = int(s)

print(10 / n)

然後啟動:

$ python -m pdb err.py

> /Users/michael/Github/learn-python3/samples/debug/err.py(2)<module>()

-> s = '0'

以引數-m pdb啟動後,pdb定位到下一步要執行的程式碼-> s = '0'。

輸入命令l(小寫字母l,不是數字1)來檢視程式碼:

(Pdb) l

  1     # err.py

  2  -> s = '0'

  3     n = int(s)

  4     print(10 / n)

輸入命令n可以單步執行程式碼:

(Pdb) n

> /Users/michael/Github/learn-python3/samples/debug/err.py(3)<module>()

-> n = int(s)

(Pdb) n

> /Users/michael/Github/learn-python3/samples/debug/err.py(4)<module>()

-> print(10 / n)

任何時候都可以輸入命令p 變數名來檢視變數:

(Pdb) p s

'0'

(Pdb) p n

0

輸入命令q結束除錯,退出程式:

(Pdb) q

這種通過pdb在命令列除錯的方法理論上是萬能的,但實在是太麻煩了,如果有一千行程式碼,要執行到第999行得敲多少命令啊。。

IDE

如果要比較爽地設定斷點、單步執行,

就需要一個支援除錯功能的IDE。

目前比較好的Python IDE有:

  1. Eclipse + PyDev外掛
  2. PyCharm

PyCharm除錯如下:

第一步,設定斷點

第二步,F8單步執行,或F9單步跳過

相關推薦

Python3簡明教程8錯誤異常

Python3之錯誤和異常 作為Python初學者,在剛學習Python程式設計時,經常會看到一些報錯資訊,在前面我們沒有提及,這章節我們會專門介紹。 Python有兩種錯誤很容易辨認:語法錯誤和異常。 語法錯誤 Python 的語法錯誤或者稱之為解析

Python程式設計基礎錯誤異常

一、簡介   Python最強大的結構之一就是它的異常處理能力,所有的標準異常都使用類來實現,都是基類Exception的成員,都從基類Exception繼承,而且都在exceptions模組中定義。Python自動將所有異常名稱放在內建名稱空間中,所以程式不必匯入exc

Python3基礎(九) 錯誤異常

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

Python3簡明教程1入門

安裝Python3 Python簡介 廣告: 中文,永久免費,零起點,視訊教程,完整示例,基於最新的Python 3版本。 Python是一種計算機程式設計語言。 世界上有很多種流行的程式語言, 比如非常難學的C語言, 非常流行的Java語言, 適合初學者

python3快速入門教程錯誤異常

Python 中(至少)有兩種錯誤:語法錯誤(syntax errors)和異常(exceptions)。 語法錯誤 語法錯誤又稱作解析錯誤: >>> while True print('Hello world') File "<stdin>", line 1 wh

Python3 錯誤異常

錯誤 異常 error python except Edit筆記內容:Python3 錯誤和異常 筆記日期:2017-11-12Python3 錯誤和異常語法錯誤異常異常處理拋出異常用戶自定義異常finally語句預定義的清理行為異常處理機制概述: 異常處理,是編程語言或計算機硬件裏的一種

Python 3 學習筆記——錯誤異常

參考 箭頭 cto last image 直接 cep 分享 一行 1. 語法錯誤 Python 的語法錯誤被稱為解析錯,語法分析器會指出出錯的代碼行,並且在最先找到的錯誤的位置標記一個小小的箭頭。 >>> while True File "&l

Python3 錯誤異常

http://www.runoob.com/python3/python3-errors-execptions.html Python3 錯誤和異常 作為Python初學者,在剛學習Python程式設計時,經常會看到一些報錯資訊,在前面我們沒有提及,這章節我們會專門介紹。 Python有兩種錯誤很容易辨

python3中的錯誤異常種類

python3中的異常包括錯誤和異常:1、錯誤在程式碼執行前的語法或邏輯錯誤SystaxError(語法錯誤)ValueError(邏輯錯誤)2.異常常見異常種類AttributeError 試圖訪問一個物件沒有的屬性,比如foo.x,但是foo沒有屬性x IOError 輸

Python3簡明教程(四)—— 流程控制分支

流程控制 bin tar chang 是否 lease ... 改變 print 我們通過 if-else 語句來做決定,來改變程序運行的流程。 if語句 語法如下: if expression: do this 如果表達式 expression

C#錯誤異常的處理

類型 div 操作 包含 文本 出現 lap aps table 錯誤的出現並不總是編寫應用程序人的原因,有時應程序會因為應用程序的最終用戶引發或運行代碼的環境而發生錯誤。無論如何,我們都應預測應用程序中出現的錯誤,並相應的進行編碼。C#處理錯誤的機制可以為每種錯誤

錯誤異常

pythonNameError 嘗試訪問一個未申明的變量ZeroDivisionError 除數為零SyntaxError 解釋器語法錯誤IndexError 請求的索引超出序列範圍KeyError 請求一個

python錯誤異常

weibo zab get mea ipp seh info tar tzu gemrc9級手瀑竿啦趾http://shufang.docin.com/kvvkh2156ugnred坎僚侗馴抗坡http://www.docin.com/app/user/userinfo?u

【技術翻譯】支持向量機簡明教程及其在pythonR下的調參

sel machine 線性 線上 ont 投影 vars 不一定 .cn 原文: Simple Tutorial on SVM and Parameter Tuning in Python and R 介紹 數據在機器學習中是重要的一種任務,支持向量機(SVM)

兄弟連學Python 錯誤異常處理

嘗試 dex 訪問 port def post 推薦 log 出現 #常見的異常 class Human: #屬性 sex = ‘man‘ age = 18 #方法 def run(self): print(‘跑

python錯誤異常,re模塊,多線程,paramiko模塊

pin 循環列表 use 可能 一起 down get mman tom 文件操作x=open(‘/etc/hosts‘) ###默認讀的方式打開x.readline()x.read()x.seek(0)y=open(‘/root/new.txt‘,‘w‘)y.writ

Python3 簡明教程學習(上)

UNC 格式 wysiwyg 常見 文本 ubuntu 存在 eve gnu 一、開始 Python 之旅交互模式 1.Ctrl + D 輸入一個 EOF 字符來退出解釋器,也可以鍵入 exit() 來退出 2.#!/usr/bin/env python3 中#!稱為 S

錯誤異常處理(7)

為什麽 nbsp 實現 str ron strong 指令 異常處理 處理 配置指令 錯誤日誌 異常處理 為什麽異常處理很方便 PHP的異常處理實現 SPL異常 錯誤和異常處理(7)

錯誤異常處理

選項 般的 out err 語法糖 stop 請求 特性 rect Python有兩種錯誤很容易辨認:語法錯誤和異常。 1 什麽是異常? 異常即是一個事件,該事件會在程序執行過程中發生,影響了程序的正常執行。 一般情況下,在Python無法正常處理程序

A-Frame簡明教程線上學習體驗

本文為A-Frame簡明教程系列文章的第零篇,大家可以到專題裡瞭解更多。 引子 今天在Github上瀏覽教程,偶然間發現一個線上學習的A-Frame教程,忍不住fork過來探索了一番,於是就有啦線上學習體驗系統,也歡迎大家到線上學習體驗的github倉庫star、f