python 44 with語句上下文管理器

2021-10-08 07:35:24 字數 2116 閱讀 6355

面試題: with語句操作的物件必須是上下文管理器。

那麼,到底什麼是上下文管理器呢?

簡單的理解,擁有 __ enter__() 和 __ exit__() 方法的物件就是上下文管理器。

__ enter__(self):進入上下文管理器自動呼叫的方法,在 with 執行之前執行。如果 有 as子句,該方法的返回值被賦值給 as 子句後的變數;該方法可以返回多個值。

__ exit__(self, exc_type, exc_value, exc_traceback):退出上下文管理器自動呼叫的方法。在with 執行之後執行(不管有無異常)。

當 with … as … 操作上下文管理器時,就會在執行語句體之前,先執行上下文管理器的 __ enter__() 方法,

然後再執行語句體,最後執行 __ exit__() 方法。

構建上下文管理器,常見的有 2 種方式:基於類實現和基於生成器實現。

在對檔案的操作中,我們通常使用with open(『filename』)as f開啟檔案,下面我們用__enter__()和__exit__()這兩個方法,自己構造乙個上下文管理器,以便能夠使用with語句操作。

class

open

(object):

def__init__

(self,filename)

: self.filename = filename

def__enter__

(self)

: self.f =

open

(self.filename)

return self.f

def__exit__

(self, exc_type, exc_val, exc_tb)

: self.f.close(

)#open就是上下文管理器。 擁有 __enter__() 和 __exit__() 方法的物件就是上下文管理器

with open(

'./example.log'

)as f:

print

(f.readlines(

))

當遇到with語句時,__ enter__()方法首先被觸發執行。__ enter__()的返回值(如果有的話)被放置在由as限定的變數中。之後開始執行with**塊中的語句。最後__ exit__()方法被觸發來執行清理工作。

這種形式的控制流與with語句塊中發生了什麼情況是沒有關聯的,出現異常時也是如此。

__ exit__(self, exc_type, exc_val, exc_tb)方法中這三個引數包含了異常型別、異常值、對掛起異常的追溯(如果出現異常的話)。__ exit__()可以選擇以某種方式來使用異常資訊,或者什麼也不幹直接忽略並返回none作為結果。如果__ exit__()的返回值為true,異常會被清理乾淨,程式會立即執行with語句塊之後的內容。

from contextlib import  contextmanager

import time

@contextmanager

deftimethis

(label)

: start = time.time(

)try

:yield

finally

: end = time.time(

)print

('{}:{}'

.format

(label,end-start)

)with timethis(

'counting:'):

n =1000000

while n>0:

n -=

1

在timethis()函式中,所有位於yield之前的**會作為上下文管理器的__ enter__()方法來執行;而所有在yield之後的**會作為__ exit__()方法執行。如果有異常產生,則會在yield語句中丟擲。

@contextmanager只適用於編寫自給自足型的上下文管理器函式

如果有一些物件(比如檔案、鎖、網路連線)需要支援在with語句中使用,那還是需要分別實現__enter__()和__exit__()方法

python 列表方法 44

alist 1,2,3,bob alice alist 0 10 列表腳標為0的字元改為10 alist 10,2,3,bob alice alist 1 3 20,30 將列表腳標為1,2 不包括3 的字元改為20和30 alist 10,20,30,bob alice alist 2 2 22,...

python學習44 使用 slots

python可以在執行期間,動態新增屬性,slots 可以限定物件的屬性,不讓隨意新增,比如下面這個例子,就是限定了score,name屬性,所以下面s1.score是成功的,s2.age就是失敗的。1 slots限定只對當前的類有效,對子類無效,如果想子類也有限定,需要子類裡面去定義slots。2...

C 44 函式引數的秘密 (上)

下面的程式輸出什麼?為什麼呢?int k 1 printf d,d n k k include int func int i,int j int main 輸出 gcc i 2,j 1 3特別說明 此處暫時沒有找到有其它求值順序的編譯器來輸出說明。由於c語言未明確規定函式引數的求值順序,其交由具體的...