目錄
我們在處理檔案的時候經常看到下面這樣的**,它即是上下文管理器:
with open('test.txt', encoding='utf-8') as fwww.cppcns.com:
print(f.readlines())
它的含義是開啟當前目錄下的test.txt檔案並列印它裡面的內容,與下面的**效果是一樣的:
f = open('test.txt', encoding='utf-8')
print(f.readlines())
f.close()
對比兩種寫法能夠發現,使用with自動執行了f.close()(關閉檔案)的這步操作,能夠少寫一點**。
那這樣的上下文管理器是怎麼實現的,下面為你講解。
如果要實現上面open的上下文管理器功能,我們可以通過建立乙個類,並新增__enter__和__exit__方法即可,如下面的**所示:
class diyopen(object):
def __init__(self, filename, **kwargs):
aznrsjli self.f = open(filename, **kwargs)
def __enter__(self):
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
print('關閉檔案')
self.f.close()
with diyopen('test.txt', encoding='utf-8') as f:
print(f.readlines())
輸出結果
['第一行\n', '第二行\n', '第三行']
關閉檔案
可以看到在我們列印出檔案內容後,自動執行了關閉檔案的操作。
那__enter__和__exit__的含義是什麼,__exit__後面的exc_type,exc_val,exc_tb又是什麼意思呢?
1)_enter_
__enter__相對來說好理解的多,當出現with語句時,它就會被觸發,有返回值時,會把返回值賦值給as宣告的變數,也就是我們上面的as f中的f。
2)_exit_
__exit__是在with執行完成後自動執行的,他後面的引數含義如下:
當with中執行的**報錯時,除了不繼續執行with包含的**外,還會將報錯資訊放入上面的三個引數中,例如下面的**:
class diyopen(object):
def __init__(self, filename,aznrsjli **kwargs):
self.f = open(filename, **kwargs)
def __enter__(self):
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
print(exc_type)
print(exc_val)
print(exc_tb)
self.f.close()
with diyopen('test.txt', encoding='utf-8') as f:
print(f.no())
輸出結果
'_io.textiowrapper' object has no attribute 'no'
需要注意的是:
python內建了contextlib這個模組用於實現上下文管理器,它是通過生成器yield實現的,這個模組讓我們不必再建立類和__enter__和__exit__了。
通過contextlib實現open功能的**如下:
from contextlib import contextmanager
@contextmanager
def diy_open(filename, **kwargs):
f = open(filename, **kwargs) # __init__
try:
yield f # __enter__
finally: # __exit__
f.close()
with diy_open('test.txt', encoding='utf-8') as f:
print(f.readlines())
本文標題: 一文帶你搞懂python上下文管理器
本文位址:
一文帶你搞懂Spring核心
容錯 減少延遲 提高效能 可用性負載均衡 總而言之,其實目的只有乙個,使用者體驗 分布式系統是由使用分發中介軟體連線的自治計算機組成的網路。它們有助於共享不同的資源和功能,為使用者提供單一且整合的連貫網路。1 在伺服器 虛擬機器 上安裝zookeeper 我這裡使用docker安裝 1 去docke...
一文帶你徹底搞懂ThreadLocal
共享變數一直是併發中的老大難問題,每個執行緒都對它有操作權,所以執行緒之間的同步很關鍵,鎖也就應運而生。這裡換乙個思路,是否可以把共享變數私有化?即每個執行緒都擁有乙份共享變數的本地副本,每個執行緒對應乙個副本,同時對共享變數的操作也改為對屬於自己的副本的操作,這樣每個執行緒處理自己的本地變數,形成...
一文帶你搞懂python中的property
通常我們在獲得變數的一些私有屬性時,必須通過方法來獲取私有屬性,並不能直接訪問 修改其數值的時候也是要通過方法去修改,這樣非常的不方便 所以python提供了一種方式,將呼叫方法的的形式轉變為訪問屬性,這樣使用非常方便 class student def init self 這是乙個私有屬性 sel...