python中的with語句


python中的with語句使用於對資源進行訪問的場合,保證不管處理過程中是否發生錯誤或者異常都會執行規定的__exit__(“清理”)操作,釋放被訪問的資源,比如有文件讀寫后自動關閉、線程中鎖的自動獲取和釋放等。

與python中with語句有關的概念有:上下文管理協議、上下文管理器、運行時上下文、上下文表達式、處理資源的代碼段。

with語句的語法格式如下:

with context_expression [as target(s)]:
    with-body

with語句的執行原理:

context_manager=context_expression
exit=type(context_manager).__exit__
value=type(context_manager).__enter__(context_manager)
exc=True
try:
    try:
        targer=value
        with-body
    except:
        exc=False
        if not exit(context_manager, *sys.exc_info()):
            raise
finally:
    if exc:
        exit(context_manager,None,None,None)

從with的執行原理中可以看出,context_expression返回的對象中必須具有__exit__和__enter__兩個方法,而且先檢查__exit__方法在檢查__enter__方法。無論在執行with-body中的函數體的過程中是否會發生異常,都會執行__exit__函數,如果沒有異常,退出函數的中參數都為None;如果發生異常,則使用sys.exc_info()返回的異常信息為參數退出,並且當__exit__方法返回True時,忽略異常,當__exit__方法返回False時,拋出異常,此時,__exit__函數中就不需要再拋出異常,只需要將__exit__函數的返回值設為False就可以了。

例子:

 自定義支持上下文管理協議的類:

不拋出異常的函數體:

拋出異常的函數體:

 

python提供了contextlib模塊,省去了寫__enter__和__exit__重復工作了。contextlib模塊提供了3個對象:contextmanager裝飾器、上下文管理器closing和nested函數。

裝飾器contextmanager用來對生成器函數進行裝飾,生成器函數被裝飾以后,返回的是一個上下文管理器。

 

  yield語句之前的代碼在__enter__函數中執行,yield語句之后的代碼在__exit__函數中執行。

closing上下文管理器包裝起來的對象必須提供close()方法。

  closing的執行原理如下:

class closing(object):
    def __init__(self,thing):
        self.thing = thing
    def __enter__(self):
        return self.thing
    def __exit__(self, *exc_info):
        self.thing.close()

  因此,closing上下文管理器包裝的對象必須提供close()函數。

nested函數可以將多個上下文管理器組織在一起,避免使用嵌套的with語句。  

with nested(A(),B(),C()) as (X,Y,Z):
    with-body

類似於:

with A() as X:
    with B() as Y:
        with C() as Z:
            with-body

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM