欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python編程ContextManager上下文管理器講解

 更新時(shí)間:2021年09月28日 17:24:40   作者:小菠蘿測(cè)試筆記  
這篇文章主要介紹了Python編程中對(duì)Context Manager上下文管理器的詳解說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步

什么是上下文管理器

官方解釋

上下文管理器是一個(gè)對(duì)象它定義了在執(zhí)行 with 語(yǔ)句時(shí)要建立的運(yùn)行時(shí)上下文上下文管理器處理進(jìn)入和退出所需的運(yùn)行時(shí)上下文以執(zhí)行代碼塊上下文管理器通常使用 with 語(yǔ)句調(diào)用,但也可以通過(guò)直接調(diào)用它們的實(shí)例方法來(lái)使用

一頓花里胡哨猛如虎,結(jié)果我也不太懂

簡(jiǎn)單一句話(huà)

同時(shí)包含 __enter__() 和 __exit__() 方法的對(duì)象就是上下文管理器

__enter__(self)

進(jìn)入上下文管理器自動(dòng)調(diào)用的方法

該方法會(huì)在 with ... as ... 代碼塊執(zhí)行之前執(zhí)行

如果 with 語(yǔ)句有 as 子句,且該方法有返回值,那么該方法的返回值會(huì)被賦值給 as 子句后的變量,最常見(jiàn)的 with open('file_path', 'w') as file: 

該方法可以返回多個(gè)值,因此在 as 子句后面也可以指定多個(gè)變量(多個(gè)變量必須由“()”括起來(lái)組成元組)

__exit__(self, exc_type, exc_value, exc_traceback)

退出上下文管理器自動(dòng)調(diào)用的方法,會(huì)返回一個(gè)布爾類(lèi)型的值

該方法會(huì)在 with ... as ... 代碼塊執(zhí)行之后執(zhí)行

如果 with ... as ... 代碼塊成功執(zhí)行結(jié)束,程序自動(dòng)調(diào)用該方法,且三個(gè)參數(shù)都為 None

如果 with ... as ... 代碼塊執(zhí)行時(shí)發(fā)生異常,通過(guò) sys.exc_info() 得到異常信息,三個(gè)參數(shù)值分別是:異常類(lèi)型、異常信息、異?;厮菪畔㈩?lèi)型

有哪些常見(jiàn)上下文管理器?

打開(kāi)文件

with open('file_path', 'w') as file:
    file.write('hello world !')

拆分了解

上下文表達(dá)式: with open('file_path', 'w') as file: 

上下文管理器: open('file_path', 'w') 

file:可以理解為資源對(duì)象

執(zhí)行順序

先執(zhí)行 open() 的 __enter__() 方法,將返回值賦值給 file

執(zhí)行 file.write('hello world !') 

最后執(zhí)行 open() 的 __exit__() 方法

自定義上下文管理器

其實(shí)有兩種方式

基于類(lèi)實(shí)現(xiàn)上下文管理器

只需要給對(duì)象添加一個(gè) __enter__ 和一個(gè) __exit__ 方法

import sys
class Resource:
    def __init__(self, name):
        self.name = name
        print("== 初始化方法 ==")
 
    def __enter__(self):
        print(f"** 進(jìn)入上下文管理器自動(dòng)調(diào)用:name is {self.name}")
        # 可以返回任意類(lèi)型的值
        return {"name": self.name}
 
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"## 退出上下文管理器自動(dòng)調(diào)用:", sys.exc_info(), exc_type, exc_val, exc_tb)
        if exc_tb is None:
            print("沒(méi)有異常時(shí)關(guān)閉資源")
        else:
            print("遇到異常時(shí)關(guān)閉資源")

通過(guò) with 來(lái)調(diào)用該上下文管理器

也稱(chēng)為:使用 with ... as ... 管理資源

with Resource("小菠蘿") as r:
    print(r)

console 輸出結(jié)果

== 初始化方法 ==
** 進(jìn)入上下文管理器自動(dòng)調(diào)用:name is 小菠蘿
{'name': '小菠蘿'}
## 退出上下文管理器自動(dòng)調(diào)用: (None, None, None) None None None
沒(méi)有異常時(shí)關(guān)閉資源

__exit__() 方法的三個(gè)參數(shù)值都是 None

with 代碼塊拋出異常

with Resource("異常小菠蘿") as r:
    print('[with代碼塊] 異常之前的代碼')
    raise Exception("拋出了 Exception")
    print('[with代碼塊] ~~~~~~~~異常之后的代碼')

console 輸出結(jié)果

== 初始化方法 ==
** 進(jìn)入上下文管理器自動(dòng)調(diào)用:name is 異常小菠蘿
[with代碼塊] 異常之前的代碼
## 退出上下文管理器自動(dòng)調(diào)用: (<class 'Exception'>, Exception('拋出了 Exception'), <traceback object at 0x10e203200>) <class 'Exception'> 拋出了 Exception <traceback object at 0x10e203200>
遇到異常時(shí)關(guān)閉資源
Traceback (most recent call last):
  File "/Users/polo/Documents/pylearn/第七章:文件相關(guān)/1_上下文管理器.py", line 36, in <module>
    raise Exception("拋出了 Exception")
Exception: 拋出了 Exception

代碼塊拋出異常的時(shí)候,可以看到 __exit__() 方法的三個(gè)參數(shù)值的確來(lái)源于 sys.exc_info() 

總結(jié)

  •  無(wú)論 with 代碼塊是否有異常,最終都會(huì)自動(dòng)調(diào)用 __exit__() 方法
  • 當(dāng)拋出異常時(shí),__exit__() 默認(rèn)返回 None,會(huì)重新拋出異常到外面,讓 with ... as ... 以外的代碼來(lái)處理異常
  • 反之,如果返回 True,就會(huì)忽略異常,不再對(duì)異常進(jìn)行處理

__exit__() 返回 True

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"## 退出上下文管理器自動(dòng)調(diào)用:", sys.exc_info(), exc_type, exc_val, exc_tb)
        if exc_tb is None:
            print("沒(méi)有異常時(shí)關(guān)閉資源")
        else:
            print("遇到異常時(shí)關(guān)閉資源")
            return True
 
 
# 再次運(yùn)行
with Resource("異常小菠蘿") as r:
    print('[with代碼塊] 拋出異常之前的代碼')
    raise Exception
    print('[with代碼塊] 拋出異常之后的代碼')

console 輸出結(jié)果

== 初始化方法 ==
** 進(jìn)入上下文管理器自動(dòng)調(diào)用:name is 異常小菠蘿
[with代碼塊] 異常之前的代碼
## 退出上下文管理器自動(dòng)調(diào)用: (<class 'Exception'>, Exception('拋出了 Exception'), <traceback object at 0x100e29200>) <class 'Exception'> 拋出了 Exception <traceback object at 0x100e29200>
遇到異常時(shí)關(guān)閉資源

不再拋出異常

基于生成器實(shí)現(xiàn)上下文管理器

通過(guò)裝飾器 contextlib.contextmanager,來(lái)定義自己所需的基于生成器的上下文管理器

from contextlib import contextmanager 
@contextmanager
def file_manager(name, mode):
    try:
        # 1、打開(kāi)文件
        file = open(name, mode)
        # 2、返回文件資源對(duì)象
        yield file
    finally:
        # 3、關(guān)閉文件
        file.close() 
with file_manager('a.txt', 'w') as file:
    print(file)
    file.write('hello world')

函數(shù) file_manager() 就是一個(gè)生成器

當(dāng)執(zhí)行 with as 語(yǔ)句時(shí),獲取文件資源對(duì)象,生成器暫停執(zhí)行,返回文件資源對(duì)象并賦值給 file

當(dāng) with 語(yǔ)句執(zhí)行完后,生成器繼續(xù)執(zhí)行剩余代碼,關(guān)閉文件,釋放資源

總結(jié)

  • 基于生成器的上下文管理器時(shí),不再用定義 __enter__() 和 __exit__() 方法
  • 但需要加上裝飾器 @contextmanager

 with 語(yǔ)句的教程

http://www.dbjr.com.cn/article/172132.htm

以上就是Python編程ContextManager上下文管理器講解的詳細(xì)內(nèi)容,更多關(guān)于Python編程Context Manager的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python中的deque基本用法詳解

    python中的deque基本用法詳解

    Python?中的?deque是一個(gè)低級(jí)別的、高度優(yōu)化的雙端隊(duì)列,對(duì)于實(shí)現(xiàn)優(yōu)雅、高效的Pythonic隊(duì)列和堆棧很有用,這篇文章主要介紹了python中的deque基本用法的相關(guān)資料,需要的朋友可以參考下
    2017-11-11
  • python 上下文管理器使用方法小結(jié)

    python 上下文管理器使用方法小結(jié)

    本文介紹了Python中的上下文管理器,以及如何結(jié)合with語(yǔ)句來(lái)使用上下文管理器,并且總結(jié)了一下with 語(yǔ)句的執(zhí)行流程。在很多情況下,with語(yǔ)句可以簡(jiǎn)化代碼,并增加代碼的健壯性。
    2017-10-10
  • pandas修改DataFrame列名的實(shí)現(xiàn)方法

    pandas修改DataFrame列名的實(shí)現(xiàn)方法

    這篇文章主要介紹了pandas修改DataFrame列名的實(shí)現(xiàn)方法, 文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)在字典中將鍵映射到多個(gè)值上的方法

    Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)在字典中將鍵映射到多個(gè)值上的方法

    這篇文章主要介紹了Python在字典中將鍵映射到多個(gè)值上的方法,涉及Python針對(duì)字典的相關(guān)映射與初始化相關(guān)操作技巧,需要的朋友可以參考下
    2018-02-02
  • python模擬點(diǎn)擊網(wǎng)頁(yè)按鈕實(shí)現(xiàn)方法

    python模擬點(diǎn)擊網(wǎng)頁(yè)按鈕實(shí)現(xiàn)方法

    在本篇文章里小編給大家整理的是一篇關(guān)于python模擬點(diǎn)擊網(wǎng)頁(yè)按鈕實(shí)現(xiàn)方法,需要的朋友們可以參考下。
    2020-02-02
  • Python定時(shí)器實(shí)例代碼

    Python定時(shí)器實(shí)例代碼

    這篇文章主要介紹了Python定時(shí)器實(shí)例代碼,向大家分享了兩部分代碼示例,一個(gè)是通過(guò)線(xiàn)程實(shí)現(xiàn)定時(shí)器timer,另一個(gè)是Python實(shí)現(xiàn)的精度可調(diào)的定時(shí)器實(shí)例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • pycharm中keras導(dǎo)入報(bào)錯(cuò)無(wú)法自動(dòng)補(bǔ)全cannot?find?reference分析

    pycharm中keras導(dǎo)入報(bào)錯(cuò)無(wú)法自動(dòng)補(bǔ)全cannot?find?reference分析

    這篇文章主要介紹了pycharm中keras導(dǎo)入報(bào)錯(cuò)無(wú)法自動(dòng)補(bǔ)全cannot?find?reference分析,文章圍繞主題展開(kāi)分析,需要的小伙伴可以參考一下
    2022-07-07
  • python urllib urlopen()對(duì)象方法/代理的補(bǔ)充說(shuō)明

    python urllib urlopen()對(duì)象方法/代理的補(bǔ)充說(shuō)明

    這篇文章主要介紹了python urllib urlopen()對(duì)象方法/代理的補(bǔ)充說(shuō)明的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Python中Pickle模塊和base64模塊的使用解析

    Python中Pickle模塊和base64模塊的使用解析

    這篇文章主要介紹了Python中Pickle模塊和base64模塊的使用解析,pickle模塊是python的標(biāo)準(zhǔn)模塊,提供了對(duì)于python數(shù)據(jù)的序列化操作,可以將數(shù)據(jù)轉(zhuǎn)換為bytes類(lèi)型,其序列化速度比json模塊要高,需要的朋友可以參考下
    2023-09-09
  • 對(duì)numpy中array和asarray的區(qū)別詳解

    對(duì)numpy中array和asarray的區(qū)別詳解

    下面小編就為大家分享一篇對(duì)numpy中array和asarray的區(qū)別詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04

最新評(píng)論