with與上下文管理器

2021-08-30 11:41:28 字數 3295 閱讀 8085

def m1():

f = open("source.txt", "w")

f.close()

如果在呼叫 write 的過程中,出現了異常進而導致後續**無法繼續執行,close 方法無法被正常呼叫,因此資源就會一直被該程式占用,無法及時釋放占用的檔案資源。

f = open("source.txt", "w")

try:

except exception as e:

print("error:", e)

finally:

f.close()

改良版本的程式是對可能發生異常的**處進行 try 捕獲,如果在 try **塊中程式出現了異常,後續**就不再執行,而直接跳轉到 except **塊。而無論如何,finally 塊的**最終都會被執行。因此,只要把 close 放在 finally **中,檔案就一定會關閉。

with open("source.txt", "r") as f:
在執行完with**塊後,系統能夠自動呼叫close()方法關閉檔案,釋放資源;語句簡潔,**量少。

建立在上下文管理器協議(實現__enter__和__exit__)之上。

上下文管理器本質就是能夠支援with操作。

任何實現了enter() 和exit() 方法的物件都可稱之為上下文管理器,上下文管理器物件可以使用 with 關鍵字。

自定義乙個上下文管理器類,讓該類實現enter() 和exit() 方法。

class file(object):

def __init__(self, filename, mode):

self.filename = filename

self.mode = mode

def __enter__(self):

print("進入上文,獲取資源")

self.f = open(self.filename, self.mode)

return self.f

def __exit__(self, exc_type, exc_val, exc_tb):

print("進入下文,關閉資源")

self.f.close()

with file('source.txt', 'r') as f:

file_data = f.read(20)

print(file_data)

# 當with遇到上下文管理器時, 就會在執行語句體之前,先執行上下文管理器的__enter__方法,

# 然後再執行語句體, 執行完語句體後, 最後執行__exit__方法

# exc_type(exception_type):異常型別

# exc_val(exception_value): 異常值

# exc_tb(exception_traceback): 異常追蹤資訊

# 異常處理:

# 把異常的type, value, traceback傳遞給__exit__方法, 讓__exit__方法處理異常

# 如果程式正常執行, 3個引數的均為none,__exit__返回的是true, 那麼這個異常就被忽略;

# 如果程式出現異常, __exit__返回的是false, 那麼這個異常將被with語句丟擲

使用 contextlib 模組中的裝飾器 contextmanager,通過 yield 將函式分割成兩部分,yield 之前的語句在enter方法中執行,yield 之後的語句在exit方法中執行。在 yield 後面的值是函式的返回值。

from contextlib import contextmanager

@contextmanager

def myopen(file_name, mode):

print("進入上文,獲取資源")

f = open(file_name, mode)

try:

yield f

finally:

print("進入下文,關閉資源")

f.close()

with myopen('source.txt', 'r') as f:

file_data = f.read(20)

print(file_data)

# 所有yield 之前的**會作為上下文管理器的enter()方法來執行

# 所有位於yield 之後的**會作為exit()方法執行

# 如果有異常發生,則會在yield中丟擲, 所以最好在對yield進行異常的捕獲,

# 使用try、finally, 此時發生的任何異常都會再次通過yield函式返回

用於資源的獲取和釋放,且可自動關閉 ,釋放資源。

以資料的連線為例:

from pymysql import connect

class jing_dong(object):

def __init__(self, database_name, password):

self.conn = connect(host='localhost', port=3306, db=str(database_name),

user='root', password=str(password), charset='utf8')

self.cur = self.conn.cursor()

def __enter__(self):

return self.cur

def __exit__(self, exc_type, exc_val, exc_tb):

self.cur.close()

self.conn.close()

with jing_dong('jing_dong', 'mysql') as f:

content = f.execute('select * from goods_brands')

t = f.fetchall()

print(t)

(1)python 提供了 with 語法用於簡化資源操作的後續清除操作,實現原理建立在上下文管理器協議(實現__enter__和__exit__)之上。

(2)with使用**中如果在開啟過程中發生異常,需要使用try-except進行捕獲。

(3)python 還提供了乙個 contextmanager 裝飾器,更進一步簡化上下管理器的實現方式。

with上下文管理器

在執行 with 語句時,首先執行 with 後面的 open 執行完 後,會將 的結果通過 as 儲存到 f 中 然後在下面實現真正要執行的操作 在操作後面,並不需要寫檔案的關閉操作,檔案會在使用完後自動關閉 實際上,在檔案操作時,並不是不需要寫檔案的關閉,而是檔案的關閉操作在 with 的上下文...

with上下文管理器

上下文管理器 任何實現了enter 和exit 法的物件都可稱之為上下 管理 器,上下 管理器物件可以使 with 關鍵字。顯然,件 file 物件也實現 了上下 管理器 方法一class file def init self,filename,mode self.filename filename...

上下文管理器

今天我們聊聊上下文管理器,當然今天所談僅為個人觀點!今天如果不是學生面試回來跟我聊到了上下文管理器,我都忘了python中還有這麼個鬼了。特別寫一篇博文我們簡單聊聊。普通的檔案操作方式,例如 情況01 1 以寫的方式開啟檔案 f open 1.txt w 2 寫入檔案內容 f.write hello...