第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開(kāi)發(fā)者教程

Python 進(jìn)階應(yīng)用教程

Python 進(jìn)階應(yīng)用教程
01 Python 的對(duì)象和類(lèi) 02 Python 類(lèi)屬性和實(shí)例屬性 03 Python類(lèi)的構(gòu)造方法、析構(gòu)方法、實(shí)例方法 04 Python 類(lèi)的私有屬性和私有方法 05 Python 類(lèi)的繼承和多繼承 06 Python 類(lèi)實(shí)戰(zhàn) 07 Python 中的迭代器實(shí)現(xiàn)原理 08 Python 中的迭代器趣味實(shí)踐 09 Python 中的生成器實(shí)現(xiàn)原理 10 Python 中的生成器趣味實(shí)踐 11 Python 中的錯(cuò)誤和異常 12 Python 中的異常處理 13 Python 中的模塊 14 Python 標(biāo)準(zhǔn)庫(kù)之 os 模塊 15 Python 標(biāo)準(zhǔn)庫(kù)之 sys 模塊 16 Python 標(biāo)準(zhǔn)庫(kù)之 math 模塊 17 Python 標(biāo)準(zhǔn)庫(kù)之 random 模塊 18 Python 標(biāo)準(zhǔn)庫(kù)之 Json 模塊 19 Python 標(biāo)準(zhǔn)庫(kù) datetime 模塊 20 Python 中的常用第三方模塊 21 Python 中的命名空間 22 Python 中的作用域 23 Python 中的文件 IO 操作 24 Python 基礎(chǔ)實(shí)戰(zhàn) 25 Python 內(nèi)置函數(shù) 26 Python 中使用正則表達(dá)式 27 使用 Python 操作 MySQL 數(shù)據(jù)庫(kù) 28 使用 Python 操作 Mongo 數(shù)據(jù)庫(kù) 29 使用 Python 操作 Redis 數(shù)據(jù)庫(kù) 30 使用 Python 發(fā)送一封郵件 31 threading 之 Thread 的使用 32 threading 之 Lock 的基本使用 33 Python 生產(chǎn)者消費(fèi)者模型 34 Python 的內(nèi)存管理與垃圾回收 35 Python 領(lǐng)域運(yùn)用:網(wǎng)絡(luò)爬蟲(chóng) 36 Python 領(lǐng)域運(yùn)用:Web 開(kāi)發(fā) 37 Python 領(lǐng)域運(yùn)用:自動(dòng)化運(yùn)維 38 Python 領(lǐng)域運(yùn)用:自動(dòng)化測(cè)試

Python 中的異常處理

程序讀文件內(nèi)容的過(guò)程可能會(huì)發(fā)生錯(cuò)誤,例如:要讀取的文件不存在。傳統(tǒng)的錯(cuò)誤處理方式如下:

  • 某個(gè)函數(shù) f 在運(yùn)行過(guò)程中可能會(huì)發(fā)生錯(cuò)誤;
  • 函數(shù) f 發(fā)生錯(cuò)誤時(shí),函數(shù) f 返回錯(cuò)誤代碼;
  • 在調(diào)用函數(shù) f 的地方,需要檢查 f 的返回值是否有錯(cuò)。

1. 傳統(tǒng)的錯(cuò)誤處理方式

1.1 返回錯(cuò)誤碼

例如,在 C 語(yǔ)言中,函數(shù) open 用于打開(kāi)一個(gè)文件,它的聲明如下:

int open(char *path, int mode);
  • 參數(shù) path 指定要打開(kāi)的文件;
  • 參數(shù) mode 指定打開(kāi)文件的方式:只讀、讀寫(xiě);
  • 函數(shù)返回一個(gè)整數(shù),該整數(shù)作為文件的標(biāo)識(shí)符;
    • 如果打開(kāi)文件成功,則返回一個(gè)非負(fù)的整數(shù);
    • 如果打開(kāi)文件失敗,則返回 -1。

因此,通過(guò)檢查函數(shù) open 的返回值,即可以判斷 open 是否成功,示例如下:

int file = open("test.txt", O_RDONLY);
if (file < 0)
    puts("open file failed");
    ...
  • 在第 1 行,函數(shù) open 打開(kāi)文件 test.txt
  • 在第 2 行,如果函數(shù) open 的返回值小于 0,則表示打開(kāi)文件失敗

1.2 缺點(diǎn)

通過(guò)錯(cuò)誤代碼的方式很容易理解,但是存在一個(gè)嚴(yán)重的問(wèn)題:用戶(hù)可能忘記了錯(cuò)誤檢查。例如:

int file = open("test.txt", O_RDONLY);
char buf[1024];
read(file, buf, sizeof(buf));
對(duì) buf 中的數(shù)據(jù)進(jìn)行處理;
close(file);
  • 在第 1 行,使用 open 打開(kāi)文件;
    • 在此處忘記對(duì) open 的返回值進(jìn)行檢查
    • 如果文件 test.txt 不存在,則 open 返回 -1,此時(shí) file 為 -1;
  • 在第 3 行,使用 read 讀取文件 file,將內(nèi)容讀取到 buf 中;
    • open 的操作失敗了,此時(shí) file 為 -1;
    • read 的第一個(gè)參數(shù) file 是一個(gè)無(wú)效的文件標(biāo)識(shí)符;
    • read 的操作必然也是失敗的;
  • 在第 4 行,對(duì) buf 中的數(shù)據(jù)進(jìn)行處理;
    • open 操作和 read 操作都發(fā)生了錯(cuò)誤;
    • buf 中的數(shù)據(jù)是無(wú)效數(shù)據(jù)。

在整個(gè)過(guò)程中,發(fā)生了兩次錯(cuò)誤:open 文件失敗、read 文件失敗,但是用戶(hù)沒(méi)有得到任何提醒。buf 中的數(shù)據(jù)是無(wú)效的,對(duì)讀取的數(shù)據(jù)進(jìn)行操作是無(wú)效的。

2. 異常的處理方式

Python 程序的執(zhí)行過(guò)程中,當(dāng)發(fā)生錯(cuò)誤時(shí)會(huì)引起一個(gè)事件,該事件被稱(chēng)為異常。異常會(huì)打斷程序的正常執(zhí)行流程,例如,編寫(xiě)程序 control-flow.py

print('AAA')
100 / 0
print('BBB') # 此行代碼不會(huì)被執(zhí)行
  • 在第 1 行,打印 AAA;
  • 在第 2 行,100 除以 0;
    • 除數(shù)是 0,Python 無(wú)法執(zhí)行該條語(yǔ)句,Python 產(chǎn)生一個(gè)異常事件通知用戶(hù);
  • 在第 3 行,打印 BBB。

程序運(yùn)行的結(jié)果如下:

AAA
Traceback (most recent call last):
  File "control-flow.py", line 2, in <module>
    100 / 0
ZeroDivisionError: division by zero
  • 在第 1 行,程序輸出 AAA;
  • 在第 3 行,指明了產(chǎn)生異常的位置:File “control-flow.py”, line 2;
    • 在文件 “control-flow.py” 的第 2 行,產(chǎn)生了異常;
    • 這行信息非常重要,用于排查錯(cuò)誤;
  • 在第 5 行,指明了異常的類(lèi)型 ZeroDivisionError: division by zero;
    • 程序的執(zhí)行流程被打斷了,程序不再執(zhí)行發(fā)生異常之后的代碼;
    • 當(dāng)發(fā)生異常時(shí)需要捕獲處理它,否則程序會(huì)中止執(zhí)行。

1.3 讀取文件

編寫(xiě)一個(gè)讀取文件內(nèi)容的 Python 程序,如果不進(jìn)行錯(cuò)誤處理,代碼如下:

file = open('test.txt')
line = file.readline()
print(line)
file.close()
  • 在第 1 行,打開(kāi)文件 test.txt;
  • 在第 2 行,讀取文件的一行;
  • 在第 3 行,打??;
  • 在第 4 行,關(guān)閉文件。

在下面的小節(jié)中,將使用異常處理對(duì)這個(gè)程序逐步進(jìn)行改進(jìn)。

2. try … except 語(yǔ)句

2.1 基本用法

Python 處理異常的基本語(yǔ)法如下:

try:
	可能發(fā)生異常的代碼塊
except:
	處理異常的代碼塊	
  • 在 try 關(guān)鍵字后,是可能發(fā)生異常的代碼塊;
    • 當(dāng)發(fā)生異常后,程序跳轉(zhuǎn)到處理異常的代碼塊;
  • 在 except 關(guān)鍵字后,是處理異常的代碼塊。

下面的程序首先拋出異常,然后捕獲該異常,代碼如下:

try:
    print('try:')
    100/0
    print('never reach here')
except:    
    print('except:')
  • 在第 2 行,打印字符串 ‘try:’;
  • 在第 3 行,執(zhí)行 100/0,除數(shù)是 0,會(huì)拋出異常;
  • 在第 4 行,拋出異常后,程序跳轉(zhuǎn)到處理異常的代碼塊,該行代碼不會(huì)被執(zhí)行;
  • 在第 6 行,捕獲異常后,打印字符串 ‘except:’。

程序運(yùn)行輸出:

try:
except:

2.2 處理指定類(lèi)型的異常

在 except 關(guān)鍵字后加上異常類(lèi)型,表示僅處理該類(lèi)型的異常,語(yǔ)法如下:

try:
	可能發(fā)生異常的代碼塊
except 異常類(lèi)型:
	處理異常的代碼塊	

下面的程序僅處理 ZeroDivisionError 類(lèi)型的異常:

try:
    print('try:')
    100/0
    print('never reach here')
except ZeroDivisionError:
    print('except ZeroDivisionError:')
  • 在第 2 行,打印字符串 ‘try:’;
  • 在第 3 行,執(zhí)行 100/0,除數(shù)是 0,會(huì)拋出 ZeroDivisionError 類(lèi)型的異常;
  • 在第 4 行,拋出異常后,程序跳轉(zhuǎn)到處理異常的代碼塊,該行代碼不會(huì)被執(zhí)行;
  • 在第 5 行,程序僅僅捕獲 ZeroDivisionError 類(lèi)型的異常;
  • 在第 6 行,捕獲異常后,打印字符串 ‘except ZeroDivisionError:’。

程序運(yùn)行輸出:

2.3 處理多種類(lèi)型的異常

可以使用多個(gè) except 關(guān)鍵字處理多種類(lèi)型的異常,語(yǔ)法如下:

try:
	可能發(fā)生異常的代碼塊
except 異常類(lèi)型1:
	處理異常的代碼塊	
except 異常類(lèi)型2:
	處理異常的代碼塊	
...		

編寫(xiě)一個(gè)能夠捕獲兩種類(lèi)型的異常的程序,首先編寫(xiě)函數(shù) generateError。函數(shù) generateError 在運(yùn)行時(shí),可能拋出兩種類(lèi)型的異常,代碼如下:

def generateError():
    import random
    number = random.randint(0, 1)
    if number == 0:
        100 / 0
    else:
        file = open('none-exsist-file')
  • 在第 3 行,產(chǎn)生一個(gè) [0, 1] 之間的隨機(jī)數(shù)
  • 在第 4 行,如果隨機(jī)數(shù)是 0
    • 在第 5 行,被除數(shù)是 0,產(chǎn)生 ZeroDivisionError 類(lèi)型的異常
  • 在第 6 行,如果隨機(jī)數(shù)是 1
    • 在第 7 行,打開(kāi)一個(gè)不存在的文件,產(chǎn)生 IOError 類(lèi)型的異常

編寫(xiě)捕獲兩種類(lèi)型異常的程序:

try:
    print('try:')
    generateError()
    print('never reach here')
except ZeroDivisionError:
    print('except ZeroDivisionError:')
except IOError:    
    print('except IOError:')
  • 在第 3 行,調(diào)用 generateError(),會(huì)隨機(jī)拋出 ZeroDivisionError 類(lèi)型或者 IOError 類(lèi)型的異常;
  • 在第 5 行,程序捕獲 ZeroDivisionError 類(lèi)型的異常;
    • 在第 6 行,捕獲異常后,打印字符串 ‘except ZeroDivisionError:’;
  • 在第 7 行,程序捕獲 IOError 類(lèi)型的異常;
    • 在第 8 行,捕獲異常后,打印字符串 ‘except IOError:’。

2.4 except … as

在捕獲異常時(shí),不僅可以獲取異常類(lèi)型,還可以獲取異常對(duì)象,語(yǔ)法如下:

except 異常類(lèi)型 as 異常對(duì)象:

下面的例子處理異常時(shí),同時(shí)獲取了異常類(lèi)型和異常對(duì)象:

try:
	list = ['www', 'imooc', 'com']
	print(list[3])
except Exception as e:
	print('except: %s' % e)
  • 在第 4 行,異常類(lèi)型為 Exception,異常對(duì)象為 e
  • 在第 5 行,打印異常對(duì)象 e

程序輸出如下:

except: list index out of range

2.5 讀取文件

下面的程序?qū)崿F(xiàn) 1.3 小節(jié)讀取文件的功能需求:

try:
    file = open('test.txt')
    line = file.readline()
    print(line)
    file.close()
except IOError:    
    print('except IOError:')
  • 在第 2 行,調(diào)用 open 函數(shù)可能會(huì)產(chǎn)生 IOError;
  • 在第 3 行,調(diào)用 readline 函數(shù)可能會(huì)產(chǎn)生 IOError;
  • 在第 5 行,關(guān)閉文件;
    • 當(dāng)異常發(fā)生時(shí),該行代碼不會(huì)被執(zhí)行;
  • 在第 6 行,捕獲 IOError 類(lèi)型的異常。

這個(gè)版本的程序的缺陷在于,當(dāng)異常發(fā)生時(shí),關(guān)閉文件的代碼不會(huì)被執(zhí)行。文件打開(kāi)后,沒(méi)有及時(shí)關(guān)閉,會(huì)帶來(lái)潛在的問(wèn)題。在下面的小節(jié)中,將對(duì)這個(gè)程序進(jìn)行改進(jìn)。

3. try … else 語(yǔ)句

3.1 基本用法

在異常處理中 else 關(guān)鍵字用于指定沒(méi)有異常時(shí)執(zhí)行的代碼塊,語(yǔ)法如下:

try:
	可能發(fā)生異常的代碼塊
except:
	處理異常的代碼塊
else:
    沒(méi)有異常時(shí)執(zhí)行的代碼塊
  • 當(dāng)發(fā)生異常時(shí),執(zhí)行 except 對(duì)應(yīng)的代碼塊
  • 當(dāng)沒(méi)有發(fā)生異常時(shí),執(zhí)行 else 對(duì)應(yīng)的代碼塊

3.2 讀取文件

下面的程序?qū)崿F(xiàn) 1.3 小節(jié)讀取文件的功能需求:

try:
    file = open('test.txt')
    line = file.readline()
except IOError:    
    print('except IOError:')
else:
    print(line)
    file.close()    
  • 在第 2 行,調(diào)用 open 函數(shù)可能會(huì)產(chǎn)生 IOError;
  • 在第 3 行,調(diào)用 readline 函數(shù)可能會(huì)產(chǎn)生 IOError;
  • 在第 5 行,關(guān)閉文件;
    • 當(dāng)異常發(fā)生時(shí),該行代碼不會(huì)被執(zhí)行;
  • 在第 6 行,else 關(guān)鍵字定義了沒(méi)有異常時(shí)執(zhí)行的代碼;
    • 在第 7 行,打印文件內(nèi)容;
    • 在第 8 行,關(guān)閉文件。

這個(gè)版本的程序的仍然存在缺陷,當(dāng)異常發(fā)生時(shí),關(guān)閉文件的代碼不會(huì)被執(zhí)行。文件打開(kāi)后,沒(méi)有及時(shí)關(guān)閉,會(huì)帶來(lái)潛在的問(wèn)題。在下面的小節(jié)中,將對(duì)這個(gè)程序進(jìn)行改進(jìn)。

4. try … finally 語(yǔ)句

4.1 基本用法

在異常處理中,finally 關(guān)鍵字用于指定無(wú)論是否發(fā)生異常都需要執(zhí)行的代碼塊,語(yǔ)法如下:

try:
	可能發(fā)生異常的代碼塊
except:
	處理異常的代碼塊
finally:
    無(wú)論是否發(fā)生異常都會(huì)執(zhí)行的代碼塊

下面的程序在執(zhí)行過(guò)程中沒(méi)有異常:

try:
    print('try:')
finally:    
    print('finally:')

程序輸出:

try:
finally:

下面的程序在執(zhí)行過(guò)程中產(chǎn)生異常:

try:
    print('try:')
    100 / 0
finally:    
    print('finally:')

程序輸出:

try:
finally:

可以看出,無(wú)論是否發(fā)生異常,finally 定義的代碼塊總是被執(zhí)行。

4.2 讀取文件

下面的程序?qū)崿F(xiàn) 1.3 小節(jié)讀取文件的功能需求:

try:
    file = open('test.txt')
  	line = file.readline()
   	print(line)
except IOError:
    print('except IOError:')
finally:
	if file:
  		file.close()
  • 在第 2 行,調(diào)用 open 函數(shù)可能會(huì)產(chǎn)生 IOError;
    • 如果在此處產(chǎn)生 IOError,變量 file 的值為空;
  • 在第 3 行,調(diào)用 readline 函數(shù)可能會(huì)產(chǎn)生 IOError;
    • 如果在此處產(chǎn)生 IOError,因?yàn)橐呀?jīng)成功打開(kāi)了文件,變量 file 的值不為空;
  • 在第 5 行,捕獲 IOError 類(lèi)型的異常;
  • 在第 7 行,finally 關(guān)鍵字定義了最終需要執(zhí)行的代碼塊;
    • 發(fā)生異常時(shí),會(huì)執(zhí)行該代碼塊;
    • 沒(méi)有異常時(shí),也會(huì)執(zhí)行該代碼塊;
  • 在第 8 行,檢查變量 file 的值是否為空;
    • 如果程序在 open 的地方發(fā)生異常,變量 file 的值為空,不需要關(guān)閉文件;
    • 如果程序在 readline 的地方發(fā)生異常,變量 file 的值不為空,需要關(guān)閉文件。

5. raise 語(yǔ)句

Python 提供了 raise 語(yǔ)句用于拋出異常,raise 語(yǔ)句有 3 種形式:

形式 功能
raise 不帶任何參數(shù)
raise Exception 把異常的名稱(chēng)作為參數(shù)
raise Exception(info) 把異常的名稱(chēng)、異常的描述信息作為參數(shù)

5.1 raise

try:
	print('try:')
	raise
	print('never reach here')
except:
	print('except:')
  • 在第 3 行,使用 raise 拋出異常;
  • 在第 4 行,不會(huì)執(zhí)行這行代碼,執(zhí)行 raise 后,程序流程跳轉(zhuǎn)到第 5 行;
  • 在第 5 行,捕獲程序拋出的異常。

程序輸出如下:

try:
except:

5.2 raise Exception

try:
	print('try:')
	raise ValueError
	print('never reach here')
except ValueError:
	print('except ValueError:')
  • 在第 3 行,使用 raise 拋出特定類(lèi)型的異常 ValueError;
  • 在第 4 行,不會(huì)執(zhí)行這行代碼,執(zhí)行 raise 后,程序流程跳轉(zhuǎn)到第 5 行;
  • 在第 5 行,捕獲程序拋出的 ValueError 類(lèi)型的異常。

程序輸出如下:

try:
except ValuseError:

5.3 raise Exception(info)

編寫(xiě)程序 raise.py 如下:

try:
	text = input('Please input digit: ')
	if not text.isdigit():
		info = '"%s" is not digit' % text
		raise ValueError(info)
except ValueError as e:
	print('except ValueError: %s' % e)	
  • 在第 2 行,提示用戶(hù)輸入數(shù)字;
  • 在第 3 行,如果用戶(hù)輸入的不是數(shù)字;
    • 在第 4 行,拼接字符串 info 用于描述錯(cuò)誤的具體信息;
    • 在第 5 行,ValueError(info) 創(chuàng)建了一個(gè)對(duì)象,包括:異常類(lèi)型和錯(cuò)誤信息,使用 raise 拋出該異常對(duì)象;
  • 在第 6 行,捕獲程序拋出的 ValueError 類(lèi)型的異常,變量 e 指向 raise 語(yǔ)句拋出的異常。

程序輸出如下:

C:\> python raise.py
Please input digit: abc
try:
except ValuseError: abc is not digit
  • 在第 2 行,用戶(hù)輸入 abc
  • 在第 4 行,提示用戶(hù)的輸入錯(cuò)誤: “abc is not digit”,具體的錯(cuò)誤信息對(duì)用戶(hù)要友好