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...