Python之上下文管理器物件

2021-09-20 03:46:43 字數 2520 閱讀 5049

在學習python的過程中,經常會用到with語句,比如在進行檔案操作時,會使用下面這樣的語法:

with

open

("1.txt"

,"r"

)as f:

print

(f.read(

))

這裡就會產生乙個疑問:f是不是就是open()函式的返回值呢?

其實並不是,這裡涉及到上下文管理器方面的知識,先來解釋一下什麼是上下文管理器物件吧。

我們都知道,python屬於鴨子型別的語言,只要乙個類實現了__getitem__()方法或者__iter__()方法,那個這個類的物件就是可迭代的。同樣,如果乙個類實現了__enter__()__exit__()方法,那麼這個類的物件就是上下文管理器物件。

當with語句開始執行時,會獲取上下文管理器物件,上面的例子中open()函式返回的就是乙個實現了__enter__()__exit__()方法的上下文管理器物件。接著會執行上下文管理器物件的__enter__()方法,如果這個方法有返回值,就會將這個返回值繫結在as後面定義的物件上面。

這裡我們通過自定義乙個上下文管理器物件來驗證一下:

class

mycontextmanager

:def

__enter__

(self)

:print

("進入__enter__方法"

)return

"hello"

def__exit__

(self, exc_type, exc_value, traceback)

:return

true

上面我們自己定義了乙個實現__enter__()方法和__exit__()方法的上下文管理器類,接著我們使用with語句來測試一下這個類:

with mycontextmanager(

)as f:

print

(f)

看一下輸出:

從結果我們可以看到,f確實是__enter__()方法的返回值。so,一定不要認為f是with後面語句的返回值,它是上下文管理器物件進入__enter__()方法後的返回值!

那麼在__exit__()方法為什麼會接受那麼多的引數呢?還有為什麼要返回true呢?

我們在使用with句法的時候,難免會在其中寫一些錯誤的**,比如1/0這種,當with語句遇到這種異常,就會進入上下文管理器物件的__exit__()方法,同時將異常類,異常值和traceback傳遞給該方法,如果該方法返回none或者true,就代表上下文管理器物件處理了該異常,執行**時就不會報錯,如果返回的不是none或true,異常就會向上丟擲。

下面來用**測試一下:

class

mycontextmanager

:def

__enter__

(self)

:print

("進入__enter__方法"

)return

"hello"

def__exit__

(self, exc_type, exc_value, traceback)

:if exc_type is

notnone

:print

("出現了異常"

)return

true

if __name__ ==

'__main__'

:with mycontextmanager(

)as f:

print

(f)1

/0

在__exit__()方法中,我們首先判斷是否出現了異常,如果有異常發生,就輸出一句話,同時返回true,告訴with語句上下文管理器物件已經處理了這個異常。

輸出結果如下,可以看到輸出結果中並沒有異常發生:

如果我們在__exit__()方法中返回其它值會是什麼結果呢?來看看執行結果:

可以看到如果__exit__()方法在發生異常時返回空字串的話,with語句一旦出現異常,就會向上丟擲。

所以__exit__()方法的作用就在於可以讓使用者定義哪些異常需要向上丟擲,哪些不需要。

今天的上下文管理器物件就介紹到這裡啦!有時間可以去看看《fluent python》的第十五章對於上下文管理器物件的詳細介紹吧!

Python之上下文管理器

以下文章總結自 head first python 讀書筆記 從python處理乙個檔案說起,在python中開啟乙個檔案時,一般的 邏輯如下 file open test.txt for line in file print line file.close 以上 主要做了3件事 1 開啟乙個檔案 ...

python 之 上下文管理器

首先說一下什麼叫上下文管理器 在python中任何實現了 enter 和 exit 方法的物件都可稱之為上下文管理器,上下文管理器物件可以使用 with 關鍵字 我們可以模擬實現乙個類,讓該類實現 enter 和 exit 方法 class file def init self,filename,m...

python之上下文管理器 with語句詳解

上下文管理器 一 基本語法with expr as var pass 以最常用的with為例 操作文字物件的時候,幾乎所有的人都會讓我們要用with open,這就是乙個上下文管理器的一種。比如 with open 1.txt as f print f.readllines 輸出結果 print t...