Python上下文管理器深入講解
引子
上下文管理器是一種簡化代碼的有力方式,其內(nèi)部也蘊(yùn)含了很多Python的編程思想,今天我們就來探究一下Python的上下文管理器。
大家之前都知道,使用Python打開文件的時(shí)候最好要使用with語句,因?yàn)檫@樣就算在文件操作中出現(xiàn)了異常,也不會(huì)導(dǎo)致內(nèi)存泄露
代碼示例:
最簡單的文件打開方式(容易導(dǎo)致內(nèi)存泄露)
f = open("./xxx.txt") f.close()
安全的文件打開方式,雖然相對(duì)復(fù)雜但是有效
# 打開文件 f = open('file.txt') try: for line in f: # 讀取文件內(nèi)容 執(zhí)行其他操作 # do_something... finally: # 保證關(guān)閉文件 f.close()
我們最經(jīng)常使用的文件打開方式
with open('file.txt', "r") as r: pass
如果一個(gè)對(duì)象要用with語句,那內(nèi)部要定義__enter__()方法和__exit__()方法。
以下為一個(gè)示例
class TestContext: def __init__(self, val): self.val = val def __enter__(self): print('進(jìn)入enter') return self.val def __exit__(self, exc_type, exc_value, exc_tb): print("進(jìn)入exit") print('exc_type: %s' % exc_type) print('exc_value: %s' % exc_value) print('exc_tb: %s' % exc_tb) with TestContext(12) as t: print("進(jìn)入with內(nèi)部") raise ValueError print('t: %s' % t)
運(yùn)行后結(jié)果如下圖
不難看出,語句的調(diào)用順序
先進(jìn)入__enter__()中, 該方法的返回值賦值給上述代碼中with后邊的t。如果with下的語句出現(xiàn)了異常就會(huì)先執(zhí)行__exit__()語句中的內(nèi)容。如果沒有發(fā)生異常,就在執(zhí)行完畢with下方語句之后執(zhí)行__exit__()語句。
概念
上下文管理協(xié)議(Context Management Protocol)
包含方法 enter() 和 exit() ,支持該協(xié)議的對(duì)象要實(shí)現(xiàn)這兩個(gè)方法。
上下文管理器(Context Manager)
支持上下文管理協(xié)議的對(duì)象,這種對(duì)象必須實(shí)現(xiàn) enter() 和 exit() 方法。
上下文管理器定義執(zhí)行with語句時(shí)要建立的運(yùn)行時(shí)上下文,負(fù)責(zé)執(zhí)行with語句塊上下文中的進(jìn)入與退出操作。
通常使用with語句調(diào)用上下文管理器,也可以通過直接調(diào)用其方法來使用。
enter()
- with語句執(zhí)行時(shí),先獲取上下文管理器對(duì)象,隨后調(diào)用其 enter()
- 若有 as var 語句,則將返回值賦給變量var
- 可以返回上下文管理器對(duì)象本身,也可以是其他相關(guān)對(duì)象
exit()
- 帶有三個(gè)參數(shù) exc_type, exc_val, exc_tb
- 若上下文管理器對(duì)象執(zhí)行無異常,則三個(gè)參數(shù)均為 None
- 若發(fā)生異常,則三個(gè)參數(shù)分別為 異常類型,異常值和tracback信息
到此這篇關(guān)于Python上下文管理器深入講解的文章就介紹到這了,更多相關(guān)Python上下文管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python調(diào)用ChatGPT的API實(shí)現(xiàn)文章生成
最近ChatGPT大火,在3.5版本后開放了接口API,所以很多人開始進(jìn)行實(shí)操,這里我就用python來為大家實(shí)現(xiàn)一下,如何調(diào)用API并提問返回文章的說明2023-03-03Python fileinput模塊如何逐行讀取多個(gè)文件
這篇文章主要介紹了Python fileinput模塊如何逐行讀取多個(gè)文件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10女神相冊(cè)密碼忘記了 我只用Python寫了20行代碼
這篇文章主要介紹了怎么樣用Python寫了20行代碼來破解找回已經(jīng)忘記的密碼,密碼的排列組合是有限的,遍歷嘗試就能夠試出正確的密碼,但這個(gè)工作要怎么用python實(shí)現(xiàn),請(qǐng)看下文2021-08-08Python PYQT界面點(diǎn)擊按鈕隨機(jī)變色功能
遇到這樣的需求寫一個(gè)pyqt界面,要求界面有一個(gè)按鈕,每次點(diǎn)擊這個(gè)按鈕,就會(huì)生成一個(gè)10以內(nèi)的隨機(jī)數(shù),當(dāng)隨機(jī)數(shù)出現(xiàn)的時(shí)候,界面底色要變成對(duì)應(yīng)的顏色,同時(shí)要求隨機(jī)數(shù)會(huì)在界面中展示出來,并且按鈕和數(shù)字的顏色不會(huì)改變,下面給大家分享源代碼,一起看看吧2024-08-08Django使用Mysql數(shù)據(jù)庫已經(jīng)存在的數(shù)據(jù)表方法
今天小編就為大家分享一篇Django使用Mysql數(shù)據(jù)庫已經(jīng)存在的數(shù)據(jù)表方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-05-05Python將主機(jī)名轉(zhuǎn)換為IP地址的方法
今天小編就為大家分享一篇Python將主機(jī)名轉(zhuǎn)換為IP地址的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-08-08