一文帶你搞懂Python上下文管理器

2022-09-21 16:45:14 字數 2187 閱讀 4487

目錄

我們在處理檔案的時候經常看到下面這樣的**,它即是上下文管理器:

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