Python with用法:自動(dòng)關(guān)閉文件進(jìn)程
實(shí)際上,Python 提供了 with 語(yǔ)句來(lái)管理資源關(guān)閉。比如可以把打開(kāi)的文件放在 with 語(yǔ)句中,這樣 with 語(yǔ)句就會(huì)幫我們自動(dòng)關(guān)閉文件。
with 語(yǔ)句的語(yǔ)法格式如下:
with context expression [as target(s)]: with 代碼塊
在上面的語(yǔ)法格式中,context_expression 用于創(chuàng)建可自動(dòng)關(guān)閉的資源。
例如,程序使用 with 語(yǔ)句來(lái)讀取文件:
import codecs
# 使用with語(yǔ)句打開(kāi)文件,該語(yǔ)句會(huì)負(fù)責(zé)關(guān)閉文件
with codecs.open("readlines_test.py", 'r', 'utf-8', buffering=True) as f:
for line in f:
print(line, end='')
程序也可以使用 with 語(yǔ)句來(lái)處理通過(guò) fileinput.input 合并的多個(gè)文件,例如如下程序:
import fileinput
# 使用with語(yǔ)句打開(kāi)文件,該語(yǔ)句會(huì)負(fù)責(zé)關(guān)閉文件
with fileinput.input(files=('test.txt', 'info.txt')) as f:
for line in f:
print(line, end='')
上面兩個(gè)程序都使用了 with 語(yǔ)句來(lái)管理資源,因此它們都不需要顯式關(guān)閉文件。
那么,with 語(yǔ)句的實(shí)現(xiàn)原理是什么?其實(shí)很簡(jiǎn)單,使用 with 語(yǔ)句管理的資源必須是一個(gè)實(shí)現(xiàn)上下文管理協(xié)議(context manage protocol)的類,這個(gè)類的對(duì)象可被稱為上下文管理器。要實(shí)現(xiàn)上下文管理協(xié)議,必須實(shí)現(xiàn)如下兩個(gè)方法:
- context_manager.__enter__():進(jìn)入上下文管理器自動(dòng)調(diào)用的方法。該方法會(huì)在 with 代碼塊執(zhí)行之前執(zhí)行。如果 with 語(yǔ)句有 as子句,那么該方法的返回值會(huì)被賦值給 as 子句后的變量;該方法可以返回多個(gè)值,因此,在 as 子句后面也可以指定多個(gè)變量(多個(gè)變量必須由“()”括起來(lái)組成元組)。
- context_manager.__exit__(exc_type, exc_value, exc_traceback):退出上下文管理器自動(dòng)調(diào)用的方法。該方法會(huì)在 with 代碼塊執(zhí)行之后執(zhí)行。如果 with 代碼塊成功執(zhí)行結(jié)束,程序自動(dòng)調(diào)用該方法,調(diào)用該方法的三個(gè)參數(shù)都為 None:如果 with 代碼塊因?yàn)楫惓6兄梗绦蛞沧詣?dòng)調(diào)用該方法,使用 sys.exc_info 得到的異常信息將作為調(diào)用該方法的參數(shù)。
通過(guò)上面的介紹不難發(fā)現(xiàn),只要一個(gè)類實(shí)現(xiàn)了 __enter__() 和 __exit__(exc_type, exc_value, exc_traceback) 方法,程序就可以使用 with 語(yǔ)句來(lái)管理它;通過(guò) __exit__() 方法的參數(shù),即可判斷出 with 代碼塊執(zhí)行時(shí)是否遇到了異常。
換而言之,上面程序所用的文件對(duì)象、FileInput 對(duì)象,其實(shí)都實(shí)現(xiàn)了這兩個(gè)方法,因此它們都可以接受 with 語(yǔ)句的管理。
下面我們自定義一個(gè)實(shí)現(xiàn)上下文管理協(xié)議的類,并使用 with 語(yǔ)句來(lái)管理它:
class FkResource:
def __init__(self, tag):
self.tag = tag
print('構(gòu)造器,初始化資源: %s' % tag)
# 定義__enter__方法,with體之前的執(zhí)行的方法
def __enter__(self):
print('[__enter__ %s]: ' % self.tag)
# 該返回值將作為as子句中變量的值
return 'fkit' # 可以返回任意類型的值
# 定義__exit__方法,with體之后的執(zhí)行的方法
def __exit__(self, exc_type, exc_value, exc_traceback):
print('[__exit__ %s]: ' % self.tag)
# exc_traceback為None,代表沒(méi)有異常
if exc_traceback is None:
print('沒(méi)有異常時(shí)關(guān)閉資源')
else:
print('遇到異常時(shí)關(guān)閉資源')
return False # 可以省略,默認(rèn)返回None也被看做是False
with FkResource('孫悟空') as dr:
print(dr)
print('[with代碼塊] 沒(méi)有異常')
print('------------------------------')
with FkResource('白骨精'):
print('[with代碼塊] 異常之前的代碼')
raise Exception
print('[with代碼塊] ~~~~~~~~異常之后的代碼')
上面程序定義了一個(gè) FkResource 類,該類定義了 __enter__() 和 __exit__() 兩個(gè)方法,因此該類的對(duì)象可以被 with 語(yǔ)句管理:
- 程序在執(zhí)行 with 代碼塊之前,會(huì)執(zhí)行 __enter__() 方法,并將該方法的返回值賦值給 as 子句后的變量。
- 程序在執(zhí)行 with 代碼塊之后,會(huì)執(zhí)行 __exit__() 方法,可以根據(jù)該方法的參數(shù)來(lái)判斷 with 代碼塊是否有異常。
程序兩次使用 with 語(yǔ)句管理 FkResource 對(duì)象。第一次,with 代碼塊沒(méi)有出現(xiàn)異常。第二次,with 代碼塊出現(xiàn)了異常。大家可以看到,使用 with 語(yǔ)句兩次對(duì) FkResource 的管理略有差異(主要是在 __exit()__ 方法中略有差異)。
運(yùn)行上面的程序,可以看到如下輸出結(jié)果:
構(gòu)造器,初始化資源: 孫悟空 [__enter__ 孫悟空]: fkit [with代碼塊] 沒(méi)有異常 [__exit__ 孫悟空]: 沒(méi)有異常時(shí)關(guān)閉資源 ------------------------------ 構(gòu)造器,初始化資源: 白骨精 [__enter__ 白骨精]: [with代碼塊] 異常之前的代碼 [__exit__ 白骨精]: 遇到異常時(shí)關(guān)閉資源 Traceback (most recent call last): File "C:\Users\mengma\Desktop\1.py", line 26, in <module> raise Exception Exception
從上面的輸出結(jié)果來(lái)看,使用 with 語(yǔ)句管理資源,程序總可以在進(jìn)入 with 代碼塊之前自動(dòng)執(zhí)行 __enter__() 方法,無(wú)論 with 代碼塊是否有異常,這個(gè)部分都是一樣的,而且 __enter__() 方法的返回值被賦值給了 as 子句后的變量,如上面的 ① 號(hào)輸出信息所示。
對(duì)于 with 代碼塊有異常和無(wú)異常這兩種情況,此時(shí)主要通過(guò) exit() 方法的參數(shù)進(jìn)行判斷,程序可針對(duì) with 代碼塊是否有異常分別進(jìn)行處理,如程序中代碼所示。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- python實(shí)現(xiàn)文件分片上傳的接口自動(dòng)化
- Python在后臺(tái)自動(dòng)解壓各種壓縮文件的實(shí)現(xiàn)方法
- python實(shí)現(xiàn)自動(dòng)清理重復(fù)文件
- Python自動(dòng)化測(cè)試中yaml文件讀取操作
- Python selenium 自動(dòng)化腳本打包成一個(gè)exe文件(推薦)
- VSCode中自動(dòng)為Python文件添加頭部注釋
- python自動(dòng)生成model文件過(guò)程詳解
- 使用python腳本自動(dòng)創(chuàng)建pip.ini配置文件代碼實(shí)例
- Python實(shí)現(xiàn)的遠(yuǎn)程文件自動(dòng)打包并下載功能示例
- python寫入文件自動(dòng)換行問(wèn)題的方法
- Python實(shí)現(xiàn)自動(dòng)整理文件的腳本
相關(guān)文章
Python爬取哆啦A夢(mèng)-伴我同行2豆瓣影評(píng)并生成詞云圖
哆啦A夢(mèng)系列是陪伴我,乃至陪伴了幾代人成長(zhǎng)的故事.50年來(lái),藤子·F·不二雄先生創(chuàng)造了竹蜻蜓,任意門,時(shí)光機(jī)器等等無(wú)數(shù)的新奇道具,讓大雄和他的小伙伴們經(jīng)歷了各種冒險(xiǎn),也經(jīng)歷了許多充滿戲劇性的啼笑皆非的日常.特意寫了這篇文章,教大家怎么繪制詞云圖,需要的朋友可以參考下2021-06-06
yolov5調(diào)用usb攝像頭及本地?cái)z像頭的方法實(shí)例
YOLOV5模型從發(fā)布到現(xiàn)在都是炙手可熱的目標(biāo)檢測(cè)模型,被廣泛運(yùn)用于各大場(chǎng)景之中,下面這篇文章主要給大家介紹了關(guān)于yolov5調(diào)用usb攝像頭及本地?cái)z像頭的相關(guān)資料,需要的朋友可以參考下2022-03-03
對(duì)python requests發(fā)送json格式數(shù)據(jù)的實(shí)例詳解
今天小編就為大家分享一篇對(duì)python requests發(fā)送json格式數(shù)據(jù)的實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
Python報(bào)錯(cuò)TypeError: unhashable type: ‘numpy.nd
在Python編程中,尤其是在處理數(shù)據(jù)時(shí),我們經(jīng)常使用numpy數(shù)組,然而,當(dāng)我們嘗試將numpy數(shù)組用作字典的鍵或集合的元素時(shí),就會(huì)遇到TypeError: unhashable type: 'numpy.ndarray',本文將探討這個(gè)錯(cuò)誤的原因,并給出幾種可能的解決方案,需要的朋友可以參考下2024-09-09
利用Pandas和Numpy按時(shí)間戳將數(shù)據(jù)以Groupby方式分組
這篇文章主要介紹了利用Pandas和Numpy按時(shí)間戳將數(shù)據(jù)以Groupby方式分組,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07

