深人了解Python上下文管理器
下面先來(lái)介紹一下with關(guān)鍵字在文件讀寫(xiě)中的應(yīng)用,簡(jiǎn)單了解上下文管理器的功能。
with語(yǔ)句
在Python文件及目錄處理方法中介紹了讀寫(xiě)大文件建議使用with語(yǔ)句,with語(yǔ)句會(huì)進(jìn)行資源的自動(dòng)管理。文件很多的情況下也會(huì)導(dǎo)致資源泄露,下面來(lái)打開(kāi)100000個(gè)文件,不進(jìn)行文件關(guān)閉操作:
for x in range(100000):
file = open('test.txt', 'w')
file_descriptors.append(file)
執(zhí)行會(huì)報(bào)如下錯(cuò)誤:
OSError: [Errno 24] Too many open files: 'test.txt'
原因就是打開(kāi)了太多文件而沒(méi)有及時(shí)關(guān)閉導(dǎo)致了資源泄露,造成系統(tǒng)崩潰。完成處理后需要對(duì)文件進(jìn)行關(guān)閉操作:
file_descriptors = []
for x in range(10000):
file = open('test.txt', 'w')
try:
file_descriptors.append(file)
finally:
file.close()
使用 with 語(yǔ)句可以完成自動(dòng)分配并且釋放資源,比上面的寫(xiě)法更加簡(jiǎn)潔:
file_descriptors = []
for x in range(10000):
with open('test.txt', 'w') as file:
file_descriptors.append(file)
上下文管理器創(chuàng)建
基于類(lèi)的上下文管理器
可以使用類(lèi)來(lái)創(chuàng)建上下文管理器,需要保證這個(gè)類(lèi)包括兩個(gè)方法:__enter__() 和__exit__()。其中,方法 __enter__() 返回需要被管理的資源,方法 __exit__() 進(jìn)行資源釋放、清理操作。
下面來(lái)模擬 Python 的打開(kāi)、關(guān)閉文件操作:
class FileManager:
def __init__(self, name, mode):
print('__init__ method called')
self.name = name
self.mode = mode
self.file = None
def __enter__(self):
print('__enter__ method called')
self.file = open(self.name, self.mode)
return self.file
def __exit__(self, exc_type, exc_value, exc_traceback):
print('__exit__ method called')
if self.file:
self.file.close()
if exc_type:
print(f'exc_type: {exc_type}')
print(f'exc_value: {exc_value}')
print(f'exc_traceback: {exc_traceback}')
return True
with FileManager('test.txt', 'w') as f:
print('開(kāi)始寫(xiě)操作')
f.write('hello world !')
print(f.closed)
執(zhí)行結(jié)果:
__init__ method called
__enter__ method called
開(kāi)始寫(xiě)操作
__exit__ method called
exc_type: <class 'Exception'>
exc_value: exception raised
exc_traceback: <traceback object at 0x000001B43C2444C8>
True
可以看到執(zhí)行順序?yàn)椋?/strong>
__init__():初始化對(duì)象 FileManager__enter__():打開(kāi)文件,返回 FileManager 對(duì)象
with中的代碼
__exit__():關(guān)閉打開(kāi)的文件流
__exit__()方法中的參數(shù)exc_type, exc_value, 和 exc_traceback 用于管理異常。
@contextmanager 裝飾器
可以使用 contextlib.contextmanager 裝飾器而不使用類(lèi)的方式來(lái)實(shí)現(xiàn)上下文管理器,它是基于生成器的上下文管理器,用以支持 with 語(yǔ)句。
仍以打開(kāi)、關(guān)閉文件為例:
from contextlib import contextmanager
@contextmanager
def file_manager(name, mode):
try:
f = open(name, mode)
yield f
finally:
f.close()
with file_manager('test.txt', 'w') as f:
f.write('hello world !')
其中 file_manager() 函數(shù)是一個(gè)生成器,yield 之前可以看成是__enter__方法中的內(nèi)容,yield 后面的是 __exit__() 內(nèi)容。加上@contextmanager裝飾器,使用基于生成器的上下文管理器時(shí),不需要定義__enter__()和__exit__()方法。
總結(jié)
上下文管理器可確保用過(guò)的資源得到迅速釋放,通常和 with 語(yǔ)句一起使用,大大提高了程序的簡(jiǎn)潔度。另外需要注意的是,編寫(xiě)基于類(lèi)或者生成器的上下文管理器時(shí),記住不要忘記釋放資源。--THE END--
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
pytorch中的hook機(jī)制register_forward_hook
這篇文章主要介紹了pytorch中的hook機(jī)制register_forward_hook,手動(dòng)在forward之前注冊(cè)hook,hook在forward執(zhí)行以后被自動(dòng)執(zhí)行,下面詳細(xì)的內(nèi)容介紹,需要的小伙伴可以參考一下2022-03-03
Python中的copy()函數(shù)詳解(list,array)
這篇文章主要介紹了Python中的copy()函數(shù)詳解(list,array),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
python編寫(xiě)adb截圖工具的實(shí)現(xiàn)源碼
adb截圖工具可用于Android手機(jī)及Android終端,Android端或者Android終端的遠(yuǎn)程截圖至本地電腦中,今天通過(guò)本文給大家介紹python編寫(xiě)adb截圖工具的實(shí)現(xiàn)源碼,感興趣的朋友一起看看吧2021-08-08
PyCharm中Matplotlib繪圖不能顯示UI效果的問(wèn)題解決
這篇文章主要介紹了PyCharm中Matplotlib繪圖不能顯示UI效果的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
Python 創(chuàng)建守護(hù)進(jìn)程的示例
這篇文章主要介紹了Python 創(chuàng)建守護(hù)進(jìn)程的示例,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-09-09

