【python】上下文管理器:協(xié)議价涝、with 語句

上下文管理器

概念:實現(xiàn)了上下文協(xié)議的對象即為上下文管理器且改。

1. 上下文表達式:with open('test.txt') as f:
2. 上下文管理器:open('test.txt')
3. f 不是上下文管理器验烧,應(yīng)該是資源對象。
上下文管理器的協(xié)議:

__enter__進入的方法
__exit__退出的方法

【作用】:一種更加優(yōu)雅的方式又跛,操作(創(chuàng)建/獲取/釋放)資源碍拆,如文件操作、數(shù)據(jù)庫連接;可以以一種更加優(yōu)雅的方式慨蓝,處理異常感混;

with 語句

談及上下文管理器,就不得不提一下with 語句礼烈,with 語句是 Pyhton 提供的一種簡化語法弧满,適用于對資源進行訪問的場合,確保不管使用過程中是否發(fā)生異常都會執(zhí)行必要的“清理”操作此熬,釋放資源庭呜,with 語句主要是為了簡化代碼操作。
語法如下:

with context as var:
    statements(語句)

【知識拓展】:線程中的鎖其實也實現(xiàn)了上下文管理協(xié)議:

import threading

withthreading.Lock():

    # 關(guān)鍵部分 

    statements

    # 關(guān)鍵部分結(jié)束 
  • with:當(dāng)文件操作執(zhí)行完成后犀忱, with語句會自動調(diào)用上下文管理器里的關(guān)閉語句來關(guān)閉文件資源募谎。
  • with 語句的實現(xiàn)原理建立在上下文管理器之上

【注釋】Python 提供了 with 語法用于簡化資源操作的后續(xù)清除操作,是try / finally的替代方法阴汇。Python 還提供了一個 contextmanager 裝飾器数冬,更進一步簡化上下管理器的實現(xiàn)方式。
【耿直插播】contextlib模塊contextmanager裝飾器可以更方便的實現(xiàn)上下文管理器搀庶。(使用裝飾器在一定程度上也簡化了代碼)
任何能夠被yield關(guān)鍵詞分割成兩部分的函數(shù)拐纱,都能夠通過裝飾器裝飾的上下文管理器來實現(xiàn)疯淫。任何在yield之前的內(nèi)容都可以看做在__enter__中的代碼執(zhí)行前的操作,而任何yield之后的操作都可以放在__exit__函數(shù)中戳玫。

下面講講關(guān)于上下文管理器的協(xié)議的用法

__enter__方法會在執(zhí)行 with 后面的語句時執(zhí)行熙掺,一般用來處理操作前的內(nèi)容。比如一些創(chuàng)建對象咕宿,初始化等币绩;
__exit__方法會在 with 內(nèi)的代碼執(zhí)行完畢后執(zhí)行,一般用來處理一些善后收尾工作府阀,比如文件的關(guān)閉缆镣,數(shù)據(jù)庫的關(guān)閉等。

__exit__方法的參數(shù)

__exit__方法中有三個參數(shù)试浙,用來接收處理異常董瞻,如果代碼在運行時發(fā)生異常,異常會被保存到這里田巴。 __exit__函數(shù)就能夠拿到關(guān)于異常的所有信息(異常類型钠糊,異常值以及異常追蹤信息),這些信息將幫助異常處理操作壹哺。

  • exc_type : 【異常類型】

  • exc_val : 【異常值】

  • exc_tb : 【異吵椋回溯追蹤】


關(guān)于上下文管理器的用法,舉個實際的例子來看看:

import sys
class lookingGlass:
    def __enter__(self):
        self.original_write = sys.stdout.write
        sys.stdout.write = self.reverse_write
        return "ASDFGHJKL"

    def reverse_write(self, text):
        self.original_write(text[::-1])

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        :param exc_type: 異常的類型
        :param exc_val: 異常實例  except ZeroDivisionError as data
        :param exc_tb: traceback對象
        :return:
        """
        sys.stdout.write = self.original_write
        return True  
       # 如果返會True 則代表已正確處理異常管宵;如果返會TRUE以外的其他值截珍,則代表異常未處理,異常會層層上拋

with lookingGlass() as what:

    print("ABC$$$$HJK")
    print(what)

import contextlib

@contextlib.contextmanager
def looking_glass():
    original_write = sys.stdout.write

    def reverse_write(text):
        # original_write(text[1:10:-1])
        original_write(text[::-1])

    sys.stdout.write = reverse_write
    yield 'AAA¥¥¥SSS'
    # 以yield為分界點箩朴, yield之后的代碼相當(dāng)于__exit__中的代碼岗喉;yield之前的代碼,相當(dāng)于__enter__中的代碼
    # yield 的值相當(dāng)于__exit__中的返回值炸庞;
    sys.stdout.write = reverse_write
print('-------$$$$------')
with looking_glass() as ABC:
    print('Zurich')
    print(ABC)
輸出結(jié)果如圖

下面钱床,我們來分析一下實現(xiàn)過程。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末燕雁,一起剝皮案震驚了整個濱河市诞丽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拐格,老刑警劉巖僧免,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捏浊,居然都是意外死亡懂衩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浊洞,“玉大人牵敷,你說我怎么就攤上這事》ㄏ#” “怎么了枷餐?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長苫亦。 經(jīng)常有香客問我毛肋,道長,這世上最難降的妖魔是什么屋剑? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任润匙,我火速辦了婚禮,結(jié)果婚禮上唉匾,老公的妹妹穿的比我還像新娘孕讳。我一直安慰自己,他們只是感情好巍膘,可當(dāng)我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布厂财。 她就那樣靜靜地躺著,像睡著了一般典徘。 火紅的嫁衣襯著肌膚如雪蟀苛。 梳的紋絲不亂的頭發(fā)上益咬,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天逮诲,我揣著相機與錄音,去河邊找鬼幽告。 笑死梅鹦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的冗锁。 我是一名探鬼主播齐唆,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼冻河!你這毒婦竟也來了箍邮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤叨叙,失蹤者是張志新(化名)和其女友劉穎锭弊,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體擂错,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡味滞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剑鞍。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡昨凡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚁署,到底是詐尸還是另有隱情便脊,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布光戈,位于F島的核電站就轧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏田度。R本人自食惡果不足惜妒御,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望镇饺。 院中可真熱鬧乎莉,春花似錦、人聲如沸奸笤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽监右。三九已至边灭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間健盒,已是汗流浹背绒瘦。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扣癣,地道東北人惰帽。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像父虑,于是被迫代替她去往敵國和親该酗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,860評論 2 361

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