第十五章 上下文管理器和else塊

本章會討論其他語言中不常見的控制流程特性,

Python用戶往往會忽略或沒有充分利用起來這些特性,

本章將要討論的特性有:

  • with 語句和上下文管理器
  • for while 和try 語句中的else字句

else語句的使用

else子句不僅能在if語句中使用,還能在for,while,try 語句中使用

for/else while/else try/else 的語義關係緊密,不過與if/else 語句的差別很大:

  • for/else:

僅當for循環運行完畢之後(沒有被break打斷)才運行else塊

  • while/else:

僅當while循環運行完畢之後(沒有被break打斷)才運行else塊

  • try/else:

僅當try塊中沒有拋出異常才運行else塊

當我們使用這一屬性來控制流程的運轉,可以使得代碼的可讀性增加,並且能省去一些重複的if else判斷

我們來用幾個代碼片段展示一下:

# 在循環中使用else模塊n# 當遍歷整個列表都沒有找到我們想要的元素時,拋出異常nmy_list = [banana, orange]nfor item in my_list:n if item == apple:n breaknelse:n raise ValueError(can not find apple)n

一開始,你可能覺得沒有必要在try/except語句中使用else語句

以下面的代碼為例,只有dangerous_call不拋出異常,after_call才會執行對吧?

# 在try except模塊中使用else塊ntry:n dangerous_call()n after_call()nexcept OSError:n log(OSerror)n

然而 after_call不應該放在try塊之中,為了清晰和準確

try快中應該只拋出預期異常的語句,因此我們應該這樣寫:

try:n dangerous_call()nexcept OSError:n log(OSerror)nelse:n after_call()n

這樣很明顯的,try塊防守的是dangerous_call可能出現的錯誤,

這樣只有在try塊不報錯的情況下,after_call才會被執行

EAFP 和 LABY

看到這兩個很陌生的辭彙是不是很頭大,實際上這是兩種不同的Python控制流之中的開發風格。

  • EAFP 取得原諒比獲取許可更容易: easier to ask for forgiveness than permission

這是一種常見的Python編程風格,先假定存在有效的鍵或者屬性,如果假定不成立,那麼捕獲異常。這種風格簡單明快,特點是代碼中有很多try/except塊

  • LBYL 三思而後行 look before you leap

這種編程風格在調用函數或者查找屬性的時候,會提前顯示的做測試條件。這種風格的特點是代碼中有很多 if/else 塊

我個人而言更加偏愛EAFP的編程風格,熟悉我的小夥伴都知道

我是通過學爬蟲來入門Python的,

在爬蟲的編寫過程中,最重要的不是速度有多快

而是能保證程序正常運行

想要做到程序不能跑著跑著就斷開,那麼異常處理就顯得至關重要了!

上下文管理器和with模塊

這裡主要說明了上下文管理器和 with 的作用,

__enter__、__exit__等方法手動地實現了一個上下文管理器,

還介紹了 @contextmanager 作為一種更優雅的實現上下文管理器

上下文管理器對象的存在的目的就是管理with語句,

就像迭代器的存在是為了管理for循環一樣

with語句的目的是簡化try/finally模式,

這種模式用於保證一段代碼運行完畢之後,

即便那段代碼由於異常會終止,

也能夠正確的執行指定的操作。

一般是用於釋放重要的資源或者還原臨時變更的狀態。

最最最最常見的例子是對文件的讀寫操作

with open(dirpath+15-1.py, r) as f:n src = f.read()nnprint(len(src))nprint (f)nf.read()nnnout:nn394n<_io.TextIOWrapper name=/.../15-1.py mode=r encoding=UTF-8>nValueError: I/O operation on closed file.nn

可以看到,我們通過with語句,能安全的對文件的讀寫進行操作

當程序走到最後一部f.read()時,

raiseValueError: I/O operation on closed file.

說明這個時候,上下文管理器已經幫我們釋放了io的操作

也就省的我們再去手動f.close()

本章小結

本章主要介紹了 else 的三種用法與上下文管理器和 with 的作用,

都是一些很常見的用法,學會了能更好幫我操作程序運行的邏輯

其次,探討了兩種不同Python控制流的編程風格。

最後,作者實現了一個上下文管理器,幫我們了解了Python上下文管理器的原理

有興趣的小夥伴可以自己去閱讀一下原文

每天的學習記錄都會 同步更新到:

微信公眾號: findyourownway

知乎專欄:zhuanlan.zhihu.com/zen-

Blog : www.ehcoblog.ml

Github: github.com/Ehco1996/


推薦閱讀:

PyQt5系列教程(22):按鈕(QPushButton)
Python 的練手項目有哪些值得推薦?
Youtube上有哪些好的python視頻教程?

TAG:Python | 流畅的Python书籍 |