摘要:上下文管理器協(xié)議包含和兩個方法。因此必要時在上下文管理器函數(shù)中使用語句防范錯誤。構(gòu)建臨時忽略指定異常的上下文管理器。這是個基類,用于定義基于類的上下文管理器。塊結(jié)束時,按照后進先出的順序調(diào)用棧中各個上下文管理器的方法。
導(dǎo)語:本文章記錄了本人在學(xué)習(xí)Python基礎(chǔ)之控制流程篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學(xué)習(xí)并交流。
本文重點:
1、掌握if語句之外的else的用法;一、if語句之外的else塊 1、else塊介紹
2、掌握上下文管理器的定義、協(xié)議、使用和with塊;
3、掌握有用的@contextmanger裝飾器。
if/else中if和else是同級對立的語句,對立是指流程經(jīng)過一層if/else語句只能對應(yīng)一種處理語句。而else在for/else,while/else,try/else語句中的功能則截然不同。后者中的else功能如下:
for/else:for循環(huán)沒有被break語句中止才運行else塊。
while/else:while循環(huán)沒有被break語句中止才運行else塊。
try/else:try塊中,沒有異常拋出時才運行else塊。
下面以for/else為例進行代碼實現(xiàn):
for i in "apple": if i.isupper(): break else: raise ValueError("No upper string was found")2、try/else塊背后的編程風(fēng)格
try/except不僅用于處理錯誤,還用于處理錯誤,這屬于EAFP編程風(fēng)格。
EAFP:easier to ask for forgiveness than permission
取得原諒比獲得許可容易。即先假定存在有效的鍵或?qū)傩裕绻俣ú怀闪?,那么捕獲異常。
LBYL:look before you leap
三思而后行。即在調(diào)用函數(shù)或查找屬性或鍵之前顯式測試前提條件。
上下文管理器(context manger):在操作文件和建立數(shù)據(jù)庫連接的時候,我們最終需要關(guān)閉資源,這就是上下文管理器存在的意義。
上下文管理器協(xié)議:包含__enter__和__exit__兩個方法。
語法:try/finally模式和with語句
實例:try/finally模式
try: f = open("test.txt", "a+") f.write("Foo ") finally: f.close()
接下來我們用with語句進行替換:
實例:with語句
with open("test.txt", "a+") as f: f.write("Foo ")
分析:open 的返回值賦值給變量 f,當(dāng)離開 with 代碼塊的時候,系統(tǒng)會自動調(diào)用 f.close() 方法。
總結(jié):with塊的功能在于簡化try/finally模式。with語句在開始運行時會在上下文管理器對象上調(diào)用__enter__,而with語句結(jié)束時會調(diào)用__exit__方法。
Tips:with語句中的as語句是可選的,as語句將__enter__返回的值綁定到as語句后的變量。值得注意的是,對于open函數(shù)必須加上as字句來獲取文件的引用。
在掌握基本上下文管理器和with語句后,我們通過自定義上下文管理器來深刻認(rèn)識with語句和__enter__以及__exit__的聯(lián)系。
實例:自定義滿足上下文管理器協(xié)議的類
class OpenFileDemo(object): def __init__(self, filename): self.filename = filename self.f = open(self.filename, "a+") return self.f def __exit__(self, exc_type, exc_value, traceback): self.f.close() if exc_type != SyntaxError: return True return False with OpenFileDemo("test.txt") as f: f.write("Foo ")3、異常處理
當(dāng)上下文管理器遇到異常時由__exit__方法處理。傳給__exit__方法的三個參數(shù)如下:
exc_type:異常類(例如SyntaxError)。
exc_value:異常實例。有時會有參數(shù)傳給異常構(gòu)造方法,例如錯誤信息,可以使用exc_value.args獲取這些參數(shù)。
traceback:traceback對象。
@contextmanger裝飾器是contextlib模塊中的工具,它可以將包含yield的語句變成上下文管理器。
其中,yield之前的語句在__enter__方法中執(zhí)行,yield之后的語句在__exit__方法執(zhí)行,yield后面的值是函數(shù)的返回值,綁定到實際調(diào)用的with中的as子句的目標(biāo)變量上。
如此可以避免編寫一個類來實現(xiàn)上下文管理器協(xié)議。
實例:@contextmanger裝飾器應(yīng)用之計時器
import contextlib import time @contextlib.contextmanager def timer(): start=time.time() yield end=time.time() usedtime=end-start print("Running time was %r seconds"%usedtime) with timer() as usedtime: time.sleep(1)
注意:一旦with塊在調(diào)用timer出現(xiàn)異常時,拋出的異常會在timer函數(shù)中的yield表達(dá)式中再次拋出。如果timer函數(shù)沒有處理異常的代碼就會導(dǎo)致函數(shù)運行中止,系統(tǒng)處于無效狀態(tài)。因此必要時在上下文管理器函數(shù)中使用try/finally語句防范錯誤。
@contextmanger集合了三個不同的Python特性:函數(shù)裝飾器、生成器和with語句,非常實用!
四、contextlib模塊中的實用工具最后說明contextlib模塊中包含的實用工具:
closing: 如果對象提供了 close() 方法,但沒有實現(xiàn) _enter__/__exit_ 協(xié)議,那么可以使用這個函數(shù)構(gòu)建上下文管理器。
suppress: 構(gòu)建臨時忽略指定異常的上下文管理器。
@contextmanager: 這個裝飾器把簡單的生成器函數(shù)變成上下文管理器,這樣就不用創(chuàng)建類去實現(xiàn)管理器協(xié)議了。
ContextDecorator: 這是個基類,用于定義基于類的上下文管理器。這種上下文管理器也能用于裝飾函數(shù),在受管理的上下文中運行整個函數(shù)。
ExitStack: 這個上下文管理器能進入多個上下文管理器。with 塊結(jié)束時,ExitStack 按照后進先出的順序調(diào)用棧中各個上下文管理器的_exit_ 方法。如果事先不知道 with 塊要進入多少個上下文管理器,可以使用這個類。例如,同時打開任意一個文件列表中的所有文件。
顯然,在這些實用工具中,使用最廣泛的是 @contextmanager 裝飾器,因此要格外留心。這個裝飾器也有迷惑人的一面,因為它與迭代無關(guān),卻要使用 yield 語句。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/44555.html
摘要:上下文管理器和塊上下文管理器協(xié)議包含和兩個方法。語句運行結(jié)束后,會在上下文管理器對象上調(diào)用方法,以此扮演子句的角色。 上下文管理器 最終,上下文管理器可能幾乎與子程序(subroutine)本身一樣重要。 在各種語言中 with 語句的作用不同,而且做的都是簡單的事,雖然可以避免不斷使用點號查找屬性,但是不會做事前準(zhǔn)備和事后清理。 if語句之外的else塊 else太個性了, 其他語言...
摘要:導(dǎo)語本文章匯總了本人在學(xué)習(xí)基礎(chǔ)之緒論篇數(shù)據(jù)結(jié)構(gòu)篇函數(shù)篇面向?qū)ο笃刂屏鞒唐驮幊唐獙W(xué)習(xí)筆記的鏈接,打算入門的朋友們可以按需查看并交流。 導(dǎo)語:本文章匯總了本人在學(xué)習(xí)Python基礎(chǔ)之緒論篇、數(shù)據(jù)結(jié)構(gòu)篇、函數(shù)篇、面向?qū)ο笃?、控制流程篇和元編程篇學(xué)習(xí)筆記的鏈接,打算入門Python的朋友們可以按需查看并交流。 第一部分:緒論篇 1、Python數(shù)據(jù)模型 第二部分:數(shù)據(jù)結(jié)構(gòu)篇 2、序列構(gòu)成...
摘要:一個典型的上下文管理器類如下處理異常正如方法名明確告訴我們的,方法負(fù)責(zé)進入上下的準(zhǔn)備工作,如果有需要可以返回一個值,這個值將會被賦值給中的??偨Y(jié)都是關(guān)于上下文管理器的內(nèi)容,與協(xié)程關(guān)系不大。 Part 1 傳送門 David Beazley 的博客 PPT 下載地址 在 Part 1 我們已經(jīng)介紹了生成器的定義和生成器的操作,現(xiàn)在讓我們開始使用生成器。Part 2 主要描述了如...
摘要:輔之以事件循環(huán),協(xié)程可用于異步處理,尤其是在中。當(dāng)前支持的協(xié)程基于增強型生成器,于版本開始采用。新的特性中,異步還有兩種新用途異步內(nèi)容管理器和迭代器。 現(xiàn)在 Python 已經(jīng)支持用協(xié)程進行異步處理。但最近有建議稱添加協(xié)程以全面完善 Python 的語言結(jié)構(gòu),而不是像現(xiàn)在這樣把他們作為生成器的一個類型。此外,兩個新的關(guān)鍵字———異步(async)和等待(await),都該添加到 Pyt...
閱讀 1211·2021-11-24 11:16
閱讀 3440·2021-11-15 11:38
閱讀 1952·2021-10-20 13:47
閱讀 559·2021-09-29 09:35
閱讀 2208·2021-09-22 15:17
閱讀 1028·2021-09-07 09:59
閱讀 3395·2019-08-30 13:21
閱讀 2919·2019-08-30 12:47