上下文管理器和 else 塊

上下文管理器

最終,上下文管理器可能幾乎與子程序(subroutine)自己同樣重要。python

在各類語言中 with 語句的做用不一樣,並且作的都是簡單的事,雖然能夠避免不
斷使用點號查找屬性,可是不會作事前準備和過後清理。編程

if語句以外的else塊

else太個性了, 其餘語言不一樣用 不用這個多線程

兩個風格

EAFP 這種就得看好哪一個else語句了

  取得原諒比得到許可容易(easier to ask for forgiveness than permission)。這是一
種常見的 Python 編程風格,先假定存在有效的鍵或屬性,若是假定不成立,那麼捕
獲異常。這種風格簡單明快,特色是代碼中有不少 try 和 except 語句。與其餘不少
語言同樣(如 C 語言),這種風格的對立面是 LBYL 風格。
接下來,詞彙表定義了 LBYL。app

LBYL 先用這個吧

  三思然後行(look before you leap)。這種編程風格在調用函數或查找屬性或鍵
以前顯式測試前提條件。與 EAFP 風格相反,這種風格的特色是代碼中有不少 if 語
句。在多線程環境中,LBYL 風格可能會在「檢查」和「行事」的空當引入條件競爭。例
如,對 if key in mapping: return mapping[key] 這段代碼來講,若是在測試
以後,但在查找以前,另外一個線程從映射中刪除了那個鍵,那麼這段代碼就會失敗。
這個問題可使用鎖或者 EAFP 風格解決。ide

上下文管理器和with塊

上下文管理器協議包含 enterexit 兩個方法。with 語句開始運行時,會在上下文管理器對象上調用 enter 方法。函數

with 語句運行結束後,會在上下文管理器對象上調用 exit 方法,以此扮演 finally 子句的角色。測試

class LookingGlass:
    def __enter__(self):
        import sys
        self.original_write = sys.stdout.write
        sys.stdout.write = self.reverse_write
        return 'JABBERWOCKY'

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

    def __exit__(self, exc_type, exc_value, traceback):
        import sys
        sys.stdout.write = self.original_write
        if exc_type is ZeroDivisionError:
            print('Please DO NOT divide by zero!')
        return True

❻ 若是一切正常,Python 調用 exit 方法時傳入的參數是 None, None, None;如
果拋出了異常,這三個參數是異常數據,以下所述。線程

解釋器調用 enter 方法時,除了隱式的 self 以外,不會傳入任何參數。傳給
exit 方法的三個參數列舉以下。code

exc_type
異常類(例如 ZeroDivisionError)。對象

exc_value
  異常實例。有時會有參數傳給異常構造方法,例如錯誤消息,這些參數可使用exc_value.args 獲取。

traceback
  traceback 對象。

@contextmanager 裝飾器 哥仍是寫全的吧

能減小建立上下文管理器的樣板代碼量,由於不用編寫一個完整的類,定義 enterexit 方法,

而只需實現有一個 yield 語句的生成器,生成想讓 enter 方法返回的值。

總結

else 不要用python哪一個沒朋友的 神奇else (不過要看懂)
上下文 with

def __enter__(self): 通常返回 self本身

def __exit__(self, exc_type, exc_value, traceback):

exc_type
異常類(例如 ZeroDivisionError)。

exc_value
  異常實例。有時會有參數傳給異常構造方法,例如錯誤消息,這些參數可使用exc_value.args 獲取。

traceback  traceback 對象。

相關文章
相關標籤/搜索