Python with語(yǔ)句和過(guò)程抽取思想
python中的with語(yǔ)句使用于對(duì)資源進(jìn)行訪問(wèn)的場(chǎng)合,保證不管處理過(guò)程中是否發(fā)生錯(cuò)誤或者異常都會(huì)執(zhí)行規(guī)定的__exit__(“清理”)操作,釋放被訪問(wèn)的資源,比如有文件讀寫后自動(dòng)關(guān)閉、線程中鎖的自動(dòng)獲取和釋放等。
與python中with語(yǔ)句有關(guān)的概念有:上下文管理協(xié)議、上下文管理器、運(yùn)行時(shí)上下文、上下文表達(dá)式、處理資源的代碼段。
with語(yǔ)句的應(yīng)用場(chǎng)景
編程中有很多操作都是配套使用的,這種配套的流程可以稱為計(jì)算過(guò)程,Python語(yǔ)言為這種計(jì)算過(guò)程專門設(shè)計(jì)了一種結(jié)構(gòu):with語(yǔ)句。比如文件處理就是這類計(jì)算過(guò)程的典型代表。
使用with語(yǔ)句前后對(duì)比
沒(méi)有使用with語(yǔ)句之前,我們是這樣打開(kāi)一個(gè)文件的:
try:
# 1. [進(jìn)入]
f = open('a.txt', 'r', encoding="utf-8")
# 2. [執(zhí)行]
print(f.read())
finally:
if f:
# 3. [退出]
f.close()
python操作文件的流程一般就是這三步:
1.[進(jìn)入]用只讀方式打開(kāi)文件
如果文件不存在,open()函數(shù)就會(huì)拋出一個(gè)IOError的錯(cuò)誤,并且給出錯(cuò)誤碼和詳細(xì)的信息告訴你文件不存在
2.[執(zhí)行]讀取文件內(nèi)容
如果文件打開(kāi)成功,接下來(lái),調(diào)用read()方法可以一次讀取文件的全部?jī)?nèi)容,Python把內(nèi)容讀到內(nèi)存,用一個(gè)str對(duì)象表示
3.[退出]關(guān)閉打開(kāi)的文件
文件使用完畢后必須關(guān)閉,因?yàn)槲募?duì)象會(huì)占用操作系統(tǒng)的資源,并且操作系統(tǒng)同一時(shí)間能打開(kāi)的文件數(shù)量也是有限的
思考為什么關(guān)閉文件操作一定要放在finallly語(yǔ)句里?
由于文件讀寫時(shí)都有可能產(chǎn)生IOError,一旦出錯(cuò),后面的f.close()就不會(huì)調(diào)用。所以,為了保證無(wú)論是否出錯(cuò)都能正確地關(guān)閉文件,我們可以使用try ... finally來(lái)實(shí)現(xiàn)。
發(fā)現(xiàn)共性:
我們發(fā)現(xiàn)其實(shí)這種過(guò)程化的語(yǔ)句有共性,比如說(shuō)在進(jìn)去一個(gè)片段前必須做某種超贊,處理工作后又需要執(zhí)行一個(gè)結(jié)束操作。比如上面的這段代碼:
finally: if f: f.close()
就可以做一個(gè)封裝。
使用with語(yǔ)句后,我們是這樣打開(kāi)一個(gè)文件的:
with open("a.txt", "r", encoding="utf-8") as f:
print(f.read())
這個(gè)with語(yǔ)句和前面的try ... finally結(jié)構(gòu)是一樣的,但是代碼更佳簡(jiǎn)潔,并且不必調(diào)用f.close()方法。
with語(yǔ)句的執(zhí)行原理
從解釋器的角度去理解with語(yǔ)句執(zhí)行流程。
with語(yǔ)句的基本形式是:
with 表達(dá)式 as 變量: 語(yǔ)句塊
這樣的一段代碼可以稱為一個(gè)上下文(context),在執(zhí)行with語(yǔ)句時(shí),解釋器會(huì)先求出表達(dá)式的值,這個(gè)值(對(duì)象)是一個(gè)上下文管理器,并且假設(shè)這個(gè)對(duì)象擁有如下類的構(gòu)造方法:
def __enter__(): # 描述進(jìn)入上下文的動(dòng)作 pass def __exit__(): # 描述退出上下文的動(dòng)作 pass
with語(yǔ)句在求出這個(gè)上下文管理器對(duì)象之后,自動(dòng)執(zhí)行進(jìn)入方法,并將這個(gè)對(duì)象的返回值賦值于 as 之后的變量,然后執(zhí)行語(yǔ)句塊。然后在退出上下文前,自動(dòng)執(zhí)行對(duì)象的退出方法。
python系統(tǒng)和標(biāo)準(zhǔn)庫(kù)的一些類型定義了這對(duì)操作,可以直接用于with語(yǔ)句。比如文件對(duì)象就直接支持這一對(duì)操作,因此可以用在with語(yǔ)句的頭部。
如果你也有類似的計(jì)算過(guò)程需要抽取出來(lái),那么可以自定義一個(gè)類,并且包含進(jìn)入、退出方法。
自定義open函數(shù)
自己實(shí)現(xiàn)才發(fā)現(xiàn),使用裝飾器和生成器就能很好的解決這個(gè)問(wèn)題,不需要用到類構(gòu)造方法來(lái)實(shí)現(xiàn);
import contextlib # 引入上下文管理包
@contextlib.contextmanager # 給函數(shù)引入裝飾器
def myopen(dir, mode):
print("開(kāi)始")
f = open(dir, mode, encoding='utf-8')
try: # 上文
yield f
finally: # 下文
print("結(jié)束")
f.close()
with myopen("a.txt", 'r') as fobj: # 把try中的yield中的f賦值給fobj
# with會(huì)將with后面的函數(shù)中的yield賦值給fobj
for i in fobj:
print(i)
# 等待上面的循環(huán)結(jié)束后,才最終執(zhí)行finally的代碼,所以這就是上下文管理
輸出:
開(kāi)始 hello,我是a.txt的第1行文字。 結(jié)束
總結(jié)
打開(kāi)文件讀寫、用pickle包完成數(shù)據(jù)的存儲(chǔ)、恢復(fù)的操作,都非常適合使用with語(yǔ)句。
pickle包的使用案例:
try:
with open("phone.pickle", "wb") as outf:
pickle.dump("13193388105", outf)
except:
print("file have errow.")
try:
with open("phone.pickle", "rb") as outf:
data = pickle.load(outf)
print(type(data))
print(data)
except:
print("file have errow.")
我總結(jié)了一下使用with語(yǔ)句的優(yōu)點(diǎn):
- 采用with語(yǔ)句的代碼更簡(jiǎn)潔
- 防止因?yàn)橥泴慺.close()而引發(fā)的錯(cuò)誤
- 一個(gè)對(duì)象的操作有進(jìn)入、退出過(guò)程可以抽取出來(lái),并做成自動(dòng)化執(zhí)行
總結(jié)
以上所述是小編給大家介紹的Python with語(yǔ)句和過(guò)程抽取思想,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
- python閉包、深淺拷貝、垃圾回收、with語(yǔ)句知識(shí)點(diǎn)匯總
- python中with語(yǔ)句結(jié)合上下文管理器操作詳解
- Python中的上下文管理器和with語(yǔ)句的使用
- 深入淺析python with語(yǔ)句簡(jiǎn)介
- Python with語(yǔ)句上下文管理器兩種實(shí)現(xiàn)方法分析
- Python中的with語(yǔ)句與上下文管理器學(xué)習(xí)總結(jié)
- 理解Python中的With語(yǔ)句
- 詳解Python中with語(yǔ)句的用法
- 理解Python中的With語(yǔ)句
- python with語(yǔ)句的原理與用法詳解
相關(guān)文章
python爬取盤搜的有效鏈接實(shí)現(xiàn)代碼
這篇文章主要介紹了python爬取盤搜的有效鏈接,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-07-07
Python中字典和集合學(xué)習(xí)小結(jié)
本文通過(guò)實(shí)例給大家介紹了python中字典和集合的知識(shí)小結(jié),非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-07-07
Python基于dom操作xml數(shù)據(jù)的方法示例
這篇文章主要介紹了Python基于dom操作xml數(shù)據(jù)的方法,結(jié)合實(shí)例形式分析了Python針對(duì)xml格式文件的加載、讀取、節(jié)點(diǎn)與屬性遍歷等相關(guān)操作技巧,需要的朋友可以參考下2018-05-05
python 使用MyQR和qrcode來(lái)制作二維碼
這篇文章主要介紹了python 如何使用MyQR和qrcode來(lái)制作二維碼,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-05-05
python os.path.isfile 的使用誤區(qū)詳解
今天小編就為大家分享一篇python os.path.isfile 的使用誤區(qū)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11
Python使用Nocalhost并開(kāi)啟debug調(diào)試的方法
Nocalhost是一種開(kāi)發(fā)者工具,支持針對(duì)Kubernetes應(yīng)用程序進(jìn)行調(diào)試和部署,這篇文章主要介紹了Python怎么使用Nocalhost并開(kāi)啟debug,需要的朋友可以參考下2023-04-04
Django通過(guò)自定義認(rèn)證后端實(shí)現(xiàn)多種登錄方式驗(yàn)證
Django提供了用戶認(rèn)證系統(tǒng),那么如何在項(xiàng)目中進(jìn)行應(yīng)用呢?在本文中小編將給大家介紹如何使用用戶認(rèn)證系統(tǒng),實(shí)現(xiàn)我們業(yè)務(wù)場(chǎng)景中常見(jiàn)的多種登錄方式驗(yàn)證。感興趣的小伙伴可以了解一下2021-12-12

