Python錯誤和異常處理

一葡幸、錯誤和異常

1.概念

兩種容易辨認的錯誤

? 語法錯誤:一些關(guān)于語法的錯誤【縮進】

? 異常:代碼完全正確软驰,但是载城,程序運行之后瞧捌,會報出 的錯誤

exception/error

代碼演示:

list1 = [23,54,6,6]
print(list1[2])
print(list1[3])
print(list1[4])  

print("over")

"""
6
6
Traceback (most recent call last):
  File "C:/Users/Administrator/Desktop/SZ-Python/Day15Code/textDemo01.py", line 4, in <module>
    print(list1[4])
IndexError: list index out of range
"""

異常特點:當程序在執(zhí)行的過程中遇到異常管跺,程序?qū)K止在出現(xiàn)異常的代碼處义黎,代碼不會繼續(xù)向下執(zhí)行

解決問題:越過異常,保證后面的代碼繼續(xù)執(zhí)行【實質(zhì):將異常暫時屏蔽起來豁跑,目的是為了讓后面的代碼的執(zhí)行不受影響】

2.常見的異常

NameError:變量未被定義

TypeError:類型錯誤

IndexError:索引異常

keyError:

ValueError:

AttributeError:屬性異常

ImportError:導入模塊的時候路徑異常

SyntaxError:代碼不能編譯

UnboundLocalError:試圖訪問一個還未被設(shè)置的局部變量

3.異常處理方式【掌握】

捕獲異常

拋出異常

3.1捕獲異常
try-except-else

語法:

? try:

? 可能存在異常的代碼

? except 錯誤表示碼 as 變量:

? 語句1

? except 錯誤表示碼 as 變量:

? 語句2

? 廉涕。。。

? else:

? 語句n

說明:

? a.try-except-else的用法類似于if-elif-else

? b.else可有可無狐蜕,根據(jù)具體的需求決定

? c.try后面的代碼塊被稱為監(jiān)測區(qū)域【檢測其中的代碼是否存在異澈撸】

? d.工作原理:首先執(zhí)行try中的語句,如果try中的語句沒有異常馏鹤,則直接跳過所有的except語句征椒,執(zhí)行else;如果try中的語句有異常湃累,則去except分支中進行匹配錯誤碼勃救,如果匹配到了,則執(zhí)行except后面的語句治力;如果沒有except匹配蒙秒,則異常仍然沒有被攔截【屏蔽】

代碼演示:

#一、try-except-else的使用

#1.except帶有異常類型
try:
    print(10 / 0)
except ZeroDivisionError as e:
    print("被除數(shù)不能為0",e)

print("~~~~")
"""
總結(jié):
a.try-except屏蔽了異常宵统,保證后面的代碼可以正常執(zhí)行
b.except ZeroDivisionError as e相當于聲明了一個ZeroDivisionError類型的變量【對象】晕讲,變量e中攜帶了錯誤的信息
"""

#2.try后面的except語句可以有多個
class Person(object):
    __slots__ = ("name")
try:
    p = Person()
    p.age = 19

    print(10 / 0)
except AttributeError as e:
    print("屬性異常",e)
except ZeroDivisionError as e:
    print("被除數(shù)不能為0",e)

print("over")

"""
總結(jié):
a.一個try語句后面可以有多個except分支
b.不管try中的代碼有多少個異常,except語句都只會被執(zhí)行其中的一個马澈,哪個異常處于try語句的前面瓢省,則先先執(zhí)行對應的except語句
c.后面的異常不會報錯【未被執(zhí)行到】
"""

#3.except語句的后面可以不跟異常類型
try:
    print(10 / 0)
except:
    print("被除數(shù)不能為0")


#4.一個except語句的后面可以跟多種異常的類型
#注意:不同的異常類型使用元組表示
try:
    print(10 / 0)
except (ZeroDivisionError,AttributeError):
    print("出現(xiàn)了異常")


#5.else分支
try:
    print(10 / 4)
except ZeroDivisionError as e:
    print("出現(xiàn)了異常",e)
else:
    print("hello")

"""
總結(jié):
a.如果try中的代碼出現(xiàn)了 異常,則直接去匹配except痊班,else分支不會被執(zhí)行
b.如果try中的代碼沒有出現(xiàn)異常勤婚,則try中的代碼正常執(zhí)行,except不會被執(zhí)行涤伐,else分支才會被執(zhí)行
"""

#6.try中不僅可以直接處理異常馒胆,還可以處理一個函數(shù)中的異常
def show():
    x = 1 / 0

try:
    show()
except:
    print("出現(xiàn)了異常")

#7.直接使用BaseException代替所有的異常
try:
    y = 10 / 0
except BaseException as e:
    print(e)

"""
總結(jié):在Python中,所有的異常其實都是類凝果,他們都有一個共同的父類BaseException祝迂,可以使用BaseException將所有異常“一網(wǎng)打盡”
"""
try-except-finally

語法:

? try:

? 可能存在異常的代碼

? except 錯誤表示碼 as 變量:

? 語句1

? except 錯誤表示碼 as 變量:

? 語句2

? 器净。型雳。。

? finally:

? 語句n

說明:不管try中的語句是否存在異常掌动,不管異常是否匹配到了except語句四啰,finally語句都會被執(zhí)行

作用:表示定義清理行為,表示無論什么情況下都需要進行的操作

代碼演示:

#二粗恢、try-except-finally的使用

#1.
try:
    print(10 / 5)
except ZeroDivisionError as e:
    print(e)

finally:
    print("finally被執(zhí)行")


#2.特殊情況
#注意:當在try或者except中出現(xiàn)return語句時柑晒,finally語句仍然會被執(zhí)行
def show():
    try:
        print(10 / 0)
        return
    except ZeroDivisionError as e:
        print(e)

    finally:
        print("finally被執(zhí)行~~~~")

show()
3.2拋出異常

raise拋出一個指定的異常對象

語法:raise 異常對象 或者 raise

說明:異常對象通過錯誤表示碼創(chuàng)建,一般來說錯誤表示碼越準確越好

代碼演示:

#raise的使用主要體現(xiàn)在自定義異常中

#1.raise表示直接拋出一個異常對象【異常是肯定存在的】
#創(chuàng)建對象的時候眷射,參數(shù)表示對異常信息的描述
try:
    raise NameError("hjafhfja")
except NameError as e:
    print(e)

print("over")

"""
總結(jié):
通過raise拋出的異常匙赞,最終還是需要通過try-except處理
"""

#2.如果通過raise拋出的異常在try中不想被處理佛掖,則可以通過raise直接向上拋出
try:
    raise NameError("hjafhfja")
except NameError as e:
    print(e)
    raise

4.assert斷言

對某個問題做一個預測,如果預測成功涌庭,則獲取結(jié)果芥被;如果預測失敗,則打印預測的信息

代碼演示:

def func(num,divNum):

    #語法:assert表達式坐榆,當出現(xiàn)異常時的信息描述
    #assert關(guān)鍵字的作用:預測表達式是否成立拴魄,如果成立,則執(zhí)行后面的代碼席镀;如果不成立匹中,則將異常的描述信息打印出來
    assert (divNum != 0),"被除數(shù)不能為0"

    return  num / divNum

print(func(10,20))
print(func(10,0))

5.異常的嵌套

代碼演示:

#需求:去拉薩,乘坐各種交通工具
print("我要去拉薩")

try:
    print("我準備乘飛機過去")
    raise Exception("由于大霧豪诲,飛機不能起飛")
    print("到拉薩了顶捷,拉薩真漂亮")
except Exception as e:
    print(e)
    try:
        print("我準備乘火車過去")
        raise  Exception("由于大暴雨,鐵路斷了")
        print("到拉薩了屎篱,拉薩真漂亮")
    except Exception as e:
        print(e)
        print("我準備跑過去")
        print("到拉薩了服赎,拉薩真漂亮")

6.自定義異常

實現(xiàn)思路:

a.定義一個類,繼承自Exception類

b.書寫構(gòu)造函數(shù)交播,屬性保存異常信息【調(diào)用父類的構(gòu)造函數(shù)】

c.重寫str函數(shù)重虑,打印異常的信息

d.定義一個成員函數(shù),用來處理自己的異常

代碼演示:

class MyException(Exception):
    def __init__(self,msg):
        super(MyException,self).__init__()
        self.msg = msg

    def __str__(self):
        return self.msg

    def handle(self):
        print("出現(xiàn)了異常")

try:
     raise MyException("自己異常的類型")
except MyException as e:
     print(e)
     e.handle()

二堪侯、文件讀寫

1.概念

在Python中嚎尤,通過打開文件生成一個文件對象【文件描述符】操作磁盤上的文件,操作主要由文件讀寫

2.普通文件的讀寫

普通文件包含:txt文件伍宦,圖片,視頻乏梁,音頻等

2.1讀文件

操作步驟:

? a.打開文件:open()

? b.讀取文件內(nèi)容:read()

? c.關(guān)閉文件:close()

說明:最后一定不要忘了文件關(guān)閉次洼,避免系統(tǒng)資源的浪費【因為一個文件對象會占用系統(tǒng)資源】

代碼演示:

#一、打開文件
"""
open(path,flag[,encoding,errors])
path:指定文件的路徑【絕對路徑和相對路徑】
flag:打開文件的方式
    r:只讀遇骑、
    rb:read binary,以二進制的方式打開卖毁,只讀【圖片,視頻落萎,音頻等】
    r+:讀寫

    w:只能寫入
    wb:以二進制的方式打開亥啦,只能寫入【圖片,視頻练链,音頻等】
    w+:讀寫

    a:append,如果一個文件不為空翔脱,當寫入的時候不會覆蓋掉原來的內(nèi)容
encoding:編碼格式:gbk,utf-8
errors:錯誤處理
"""
path = r"C:\Users\Administrator\Desktop\SZ-Python\Day15\筆記\致橡樹.txt"
#調(diào)用open函數(shù),得到了文件對象
f = open(path,"r",encoding="gbk")

"""
注意:
a.以r的方式打開文件時媒鼓,encoding是不是必須出現(xiàn)
    如果文件格式為gbk,可以不加encoding="gbk"
    如果文件格式為utf-8,必須添加encoding="utf-8"
b届吁。如果打開的文件是圖片错妖,音頻或者視頻等,打開方式采用rb,但是疚沐,此時暂氯,不能添加encoding="xxx"
"""

#二、讀取文件內(nèi)容
#1.讀取全部內(nèi)容   ***********
#str = f.read()
#print(str)

#2.讀取指定的字符數(shù)
#注意:如果每一行的結(jié)尾有個"\n",也被識別成字符
"""
str1 = f.read(2)
print(str1)
str1 = f.read(2)
print(str1)
str1 = f.read(2)
print(str1)


#3.讀取整行亮蛔,不管該行有多少個字符    *********
str2 = f.readline()
print(str2)
str2 = f.readline()
print(str2)
"""

#4.讀取一行中的指定的字符
#str3 = f.readline(3)
#print(str3)

#5.讀取全部的內(nèi)容痴施,返回的結(jié)果為一個列表,每一行數(shù)據(jù)為一個元素
#注意:如果指明參數(shù)究流,則表示讀取指定個數(shù)的字符
str4 = f.readlines()
print(str4)

#三晾剖、關(guān)閉文件
f.close()

其他寫法:

#1.讀取文件的簡寫形式
#with open()  as 變量

#好處:可以自動關(guān)閉文件,避免忘記關(guān)閉文件導致的資源浪費
path = "致橡樹.txt"
with open(path,"r",encoding="gbk") as f:
    result = f.read()
    print(result)

#2.
try:
    f1 = open(path,"r",encoding="gbk")
    print(f1.read())
except FileNotFoundError as e:
    print("文件路徑錯誤",e)
except LookupError as e:
    print("未知的編碼格式",e)
except UnicodeDecodeError as e:
    print("讀取文件解碼錯誤",e)
finally:
    if f1:
        f1.close()

讀取圖片等二進制文件:

#1.
f = open("dog.jpg","rb")

result = f.read()
print(result)

f.close()

#2
with open("dog.jpg","rb") as f1:
    f1.read()

#注意:讀取的是二進制文件梯嗽,讀取到的內(nèi)容為\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xdb\x0
2.2寫文件

操作步驟:

? a.打開文件:open()

? b.寫入數(shù)據(jù):write()

? c.刷新管道【內(nèi)部緩沖區(qū)】:flush()

? d.關(guān)閉文件:close()

代碼演示:

path = "file1.txt"

#1.打開文件
#注意:寫入文件的時候齿尽,文件可以不存在,當open的時候會自動創(chuàng)建文件
#讀取文件的時候灯节,文件必須先存在循头,才能open
f = open(path,"w",encoding="utf-8")

#2.寫入數(shù)據(jù)
#注意:將數(shù)據(jù)寫入文件的時候,默認是沒有換行的炎疆,如果向換行卡骂,則可以手動添加\n
f.write("Python1805高薪就業(yè),走上人生巔峰")

#3.刷新數(shù)據(jù)緩沖區(qū)
#作用:加速數(shù)據(jù)的流動形入,保證緩沖區(qū)的流暢
f.flush()

#4.關(guān)閉文件
f.close()

#簡寫形式
with open(path,"w",encoding="utf-8") as f1:
    f1.write("hello")
    f.flush()

3.編碼和解碼

編碼:encode全跨,字符串類型轉(zhuǎn)換為字節(jié)類型

解碼:decode,字節(jié)類型轉(zhuǎn)換為字符串類型

注意:編碼和解碼的格式必須保持一致

代碼演示:

path = "file2.txt"

#編碼:字符串----》字節(jié)
with open(path,"wb") as f1:
    str = "today is a good day 今天是個好天氣"
    f1.write(str.encode("utf-8"))

#解碼:字節(jié)----->字符串
with open(path,"rb") as f2:
    data = f2.read()
    print(data)
    print(type(data))

    newData = data.decode("utf-8")
    print(newData)
    print(type(newData))

4.csv文件的讀寫

csv:逗號分隔值【Comma Separated Values】

一種文件格式亿遂,.csv,本質(zhì)是一個純文本文件浓若,可以作為不同程序之間數(shù)據(jù)交互的格式

打開方式:記事本,excel

4.1讀文件

代碼演示:

#C:\Users\Administrator\Desktop\SZ-Python\Day15\筆記\text.csv
import  csv


#方式一:三部曲
def readCsv1(path):
    #1.打開文件
    csvFile = open(path,"r")

    #2.將文件對象封裝成可迭代對象
    reader= csv.reader(csvFile)

    #3.讀取文件內(nèi)容
    #遍歷出來的結(jié)果為列表
    for item in reader:
        print(item)

    #4.關(guān)閉文件
    csvFile.close()

readCsv1(r"C:\Users\Administrator\Desktop\SZ-Python\Day15\筆記\text.csv")

#方式二:簡寫
def readCsv2(path):
    with open(path,"r") as f:
        reader = csv.reader(f)
        for item in reader:
            print(item)

readCsv2(r"C:\Users\Administrator\Desktop\SZ-Python\Day15\筆記\text.csv")
4.2寫文件

代碼演示:

import  csv

#1.從列表寫入數(shù)據(jù)
def writeCsv1(path):
    infoList = [['username', 'password', 'age', 'address'],['zhangsan', 'abc123', '17', 'china'],['lisi', 'aaabbb', '10', 'england']]

    #1.打開文件
    #注意:如果不設(shè)置newline蛇数,每一行會自動有一個空行
    csvFile = open(path,"w",newline="")

    #2.將文件對象封裝成一個可迭代對象
    writer = csv.writer(csvFile)

    #3.寫入數(shù)據(jù)
    for i in range(len(infoList)):
        writer.writerow(infoList[i])

    #4.關(guān)閉文件
    csvFile.close()

writeCsv1("file3.csv")

#2.從字典寫入文件
def writeCsv2(path):
    dic = {"張三":123,"李四":456,"王麻子":789}
    csvFile = open(path, "w", newline="")
    writer = csv.writer(csvFile)

    for key in dic:
        writer.writerow([key,dic[key]])

    csvFile.close()

#3.簡寫形式
def writeCsv3(path):
    infoList = [['username', 'password', 'age', 'address'], ['zhangsan', 'abc123', '17', 'china'],
                ['lisi', 'aaabbb', '10', 'england']]
    with open(path, "w", newline="") as f:
        writer = csv.writer(f)

        for rowData in infoList:
            writer.writerow(rowData)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挪钓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子耳舅,更是在濱河造成了極大的恐慌碌上,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浦徊,死亡現(xiàn)場離奇詭異馏予,居然都是意外死亡,警方通過查閱死者的電腦和手機盔性,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門霞丧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人纯出,你說我怎么就攤上這事蚯妇》罅牵” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵箩言,是天一觀的道長硬贯。 經(jīng)常有香客問我,道長陨收,這世上最難降的妖魔是什么饭豹? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮务漩,結(jié)果婚禮上拄衰,老公的妹妹穿的比我還像新娘。我一直安慰自己饵骨,他們只是感情好翘悉,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著居触,像睡著了一般妖混。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上轮洋,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天制市,我揣著相機與錄音,去河邊找鬼弊予。 笑死祥楣,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的汉柒。 我是一名探鬼主播误褪,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼竭翠!你這毒婦竟也來了振坚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤斋扰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后啃洋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體传货,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年宏娄,在試婚紗的時候發(fā)現(xiàn)自己被綠了问裕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡孵坚,死狀恐怖粮宛,靈堂內(nèi)的尸體忽然破棺而出窥淆,到底是詐尸還是另有隱情,我是刑警寧澤巍杈,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布忧饭,位于F島的核電站,受9級特大地震影響筷畦,放射性物質(zhì)發(fā)生泄漏词裤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一鳖宾、第九天 我趴在偏房一處隱蔽的房頂上張望吼砂。 院中可真熱鬧,春花似錦鼎文、人聲如沸渔肩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽周偎。三九已至,卻和暖如春蚤假,著一層夾襖步出監(jiān)牢的瞬間栏饮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工磷仰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留袍嬉,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓灶平,卻偏偏與公主長得像伺通,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子逢享,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容