學習python:異常處理

簡介

本文主要介紹python的異常處理機制,包括:

  1. 如何使用異常處理
  2. 異常的傳遞
  3. 拋出異常

由於比較簡單,因此這裏介紹的不是很詳細。

有一些代碼來源於網絡。

如何使用異常處理

所有的面嚮對象語言對異常的處理方式大同小異,在python中的處理異常的結構如下:

try:
    # 可能出錯的程序
except (Exception1, Exception2):     # 注意,python3中如果同時處理多個異常,需要將多個異常放在元組中。
    # 捕獲到異常後對應的處理方法
except Exception as e:
    # 捕獲到異常後對應的處理方法
    print(e)
    raise
else# 如果沒有捕獲到異常對應處理方法
finally:
    # 觸發異常或者不觸發異常都需要處理的部分

接下來我們對上述結構逐一介紹。

try … except

try裏面放可能出現問題的代碼
except裏面放捕獲到錯誤之後的處理的方法

try:
    print(num)
except NameError as e:
    print('捕獲到的錯誤信息:',e)

# Output:
捕獲到的錯誤信息: name 'num' is not defined

except 捕獲多個異常

直接在except將多個異常的名字放在元組裏即可:

try:
    open('hahaha')
except (NameError, IOError):
    print('catch exception')

# Output
catch exception

捕獲所有異常

Exception類是所有異常類的父類,可以直接用Exception接收所有異常。

try:
    print(num)
except Exception as e:
    print(e)

# Output:
 name 'num' is not defined

else

當沒有異常使,可以用else處理。

try:
    num = 100
    print(num)
except Exception as e:
    print(e)
else:
    print('not catch IOError!')

# Output 
100
not catch IOError!

try … finally

無論檢測到還是檢測不到異常,有些代碼都需要執行,此時放在finally裏。

import time
try:
    f = open('test.txt')
    try:
        while True:
            content = f.readline()
            if len(content) == 0:
                break
            time.sleep(2)
            print(content)
    except:
        #如果在讀取文件的過程中,產生了異常,那麼就會捕獲到
        #比如 按下了 ctrl+c
        pass
    finally:
        f.close()
        print('關閉文件')
except:
    print("沒有這個文件")

異常的傳遞

使用try ... except捕獲異常還有一個好處,即異常可以跨越多層進行傳遞。如下面的例子:

def test1():
    print("----test1-1----")
    print(num)
    print("----test1-2----")

def test3():
    try:
        print("----test3-1----")
        test1()
        print("----test3-2----")
    except Exception as result:
        print("捕獲到了異常,信息是:%s"%result)

    print("----test3-3----")

test3()

#Output
----test3-1----
----test1-1----
捕獲到了異常,信息是:global name 'num' is not defined
----test3-3----

這樣我們就可以不必在每個可能出現錯誤的地方都寫上try,而只需要在合適的層次進行處理即可。

拋出異常

拋出已有異常

可以通過raise來將捕獲到的異常再拋出去。如下:

class Test(object):
    def __init__(self, switch):
        self.switch = switch #開關
    def calc(self, a, b):
        try:
            return a/b
        except Exception as result:
            if self.switch:
                print("捕獲開啓,已經捕獲到了異常,信息如下:")
                print(result)
            else:
                #重新拋出這個異常,此時就不會被這個異常處理給捕獲到,從而觸發默認的異常處理
                raise

a = Test(True)
a.calc(11,0)

print("----------------------華麗的分割線----------------")

a.switch = False
a.calc(11,0)

#Output 
捕獲開啓,已經捕獲到了異常,信息如下:
integer division or modulo by zero
----------------------華麗的分割線----------------
Traceback (most recent call last):
  File "test.py", line 23, in <module>
    a.calc(11,0)
  File "test.py", line 7, in calc
    return a/b
ZeroDivisionError: integer division or modulo by zero

拋出自定義異常

自定義異常需要繼承Exception類即可,如下:

# -*- coding:utf8 -*- 
class NumError(Exception):
    def __init__(self, num, max_):
        self.num = num
        self.max_ = max_

try:
    num = 101
    if num > 100:
        raise NumError(num, 100)
except NumError as e:
    print('%d is too large, max is %d' %(e.num, e.max_))

# Output
101 is too large, max is 100
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章