使用Python實(shí)現(xiàn)with結(jié)構(gòu)的@contextmanager方法詳解
常見with結(jié)構(gòu)
常見的with結(jié)構(gòu)是在進(jìn)行文件操作時,比如
# 中規(guī)中矩的寫法
f = open("test.txt", "w")
f.write("hello world!")
f.close()
# 采用with結(jié)構(gòu)
with open("test.txt", "w") as f:
f.write("hello world!")這個結(jié)構(gòu)的好處,一個是簡潔,一個是當(dāng)我們對文件操作的邏輯很長的時候,不會因?yàn)橥岁P(guān)閉文件而造成不必要的錯誤。
類似的,當(dāng)我們在某些時候不希望遺忘一些重要的語句的時候,可以自己封裝個with結(jié)構(gòu),比如關(guān)閉數(shù)據(jù)庫鏈接等情況。
一般實(shí)現(xiàn)方法
with結(jié)構(gòu)一般的實(shí)現(xiàn)方法是在定義類的時候重載__enter__方法和__exit__方法
比如我們可以通過如下代碼來模擬一下上面兩段代碼前者到后者的轉(zhuǎn)化
# -*- coding: utf-8 -*-
class myOpen():
def __init__(self, name, state):
self.f = open(name, state)
# 返回值是with...as...中as出來的東西,如下面的f
def __enter__(self):
return self.f
# 在with...as...語句塊自動執(zhí)行完之后執(zhí)行
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
if __name__ == "__main__":
with myOpen("test.txt", "w") as f:
f.write("hello world!")@contextmanager方法
好像上面這種方法實(shí)現(xiàn)起來with結(jié)構(gòu)有那么一點(diǎn)點(diǎn)麻煩,那么就進(jìn)入主題吧,有一種逼格又高,又簡便的方法,先上代碼,仍以打開文件為例:
# -*- coding: utf-8 -*-
from contextlib import contextmanager
@contextmanager
def myOpen(name, state):
try:
f = open(name, state)
yield f
finally:
f.close()
if __name__ == "__main__":
with myOpen("test.txt", "w") as f:
f.write("hello world!")可以看出這里只要定義一個函數(shù),然后在它的頭部加上@contextmanager就好了
這個函數(shù)應(yīng)該怎么定義呢?我們?nèi)ピ创a里看一下就好,里面給出了詳細(xì)的注釋
def contextmanager(func):
"""@contextmanager decorator.
Typical usage:
@contextmanager
def some_generator(<arguments>):
<setup>
try:
yield <value>
finally:
<cleanup>
This makes this:
with some_generator(<arguments>) as <variable>:
<body>
equivalent to this:
<setup>
try:
<variable> = <value>
<body>
finally:
<cleanup>
"""
@wraps(func)
def helper(*args, **kwds):
return GeneratorContextManager(func(*args, **kwds))
return helper通過注釋我們可以看到,我們可以通過給一個try…finally…結(jié)構(gòu)的函數(shù)頭部加上@contextmanager就可以通過with…as…結(jié)構(gòu)來調(diào)用它了
這樣try塊中yield的數(shù)據(jù)被as出來,finally塊中的數(shù)據(jù)在with..as..塊結(jié)束的時候被執(zhí)行。
到此這篇關(guān)于使用Python實(shí)現(xiàn)with結(jié)構(gòu)的@contextmanager方法詳解的文章就介紹到這了,更多相關(guān)Python實(shí)現(xiàn)with結(jié)構(gòu)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python 在區(qū)塊鏈智能合約開發(fā)中的應(yīng)用與實(shí)踐小結(jié)
Python作為一種廣泛應(yīng)用的編程語言,在區(qū)塊鏈智能合約開發(fā)中扮演著重要角色,通過使用Python框架如Brownie和Web3.py,開發(fā)者可以輕松編寫和部署智能合約,感興趣的朋友一起看看吧2024-09-09
解讀keras中的正則化(regularization)問題
這篇文章主要介紹了解讀keras中的正則化(regularization)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
python實(shí)現(xiàn)rar解壓和壓縮的方法(附源碼)
數(shù)據(jù)量現(xiàn)在越來越大,壓縮文件在日常生活中很常用,這篇文章主要給大家介紹了關(guān)于python實(shí)現(xiàn)rar解壓和壓縮的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
Pycharm?cannot?set?up?a?python?SDK問題的原因及解決方法
這篇文章主要給大家介紹了關(guān)于Pycharm?cannot?set?up?a?python?SDK問題的原因及解決方法,這個問題已經(jīng)不是第一次出現(xiàn)了,所以干脆總結(jié)下,需要的朋友可以參考下2022-06-06
tensor和numpy的互相轉(zhuǎn)換的實(shí)現(xiàn)示例
這篇文章主要介紹了tensor和numpy的互相轉(zhuǎn)換的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08

