一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python編程ContextManager上下文管理器講解

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

2022-01-13 00:23小菠蘿測試筆記 Python

這篇文章主要介紹了Python編程中對Context Manager上下文管理器的詳解說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步

什么是上下文管理器

官方解釋

上下文管理器是一個對象它定義了在執行 with 語句時要建立的運行時上下文上下文管理器處理進入和退出所需的運行時上下文以執行代碼塊上下文管理器通常使用 with 語句調用,但也可以通過直接調用它們的實例方法來使用

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

簡單一句話

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

__enter__(self)

進入上下文管理器自動調用的方法

該方法會在 with ... as ... 代碼塊執行之前執行

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

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

__exit__(self, exc_type, exc_value, exc_traceback)

退出上下文管理器自動調用的方法,會返回一個布爾類型的值

該方法會在 with ... as ... 代碼塊執行之后執行

如果 with ... as ... 代碼塊成功執行結束,程序自動調用該方法,且三個參數都為 None

如果 with ... as ... 代碼塊執行時發生異常,通過 sys.exc_info() 得到異常信息,三個參數值分別是:異常類型、異常信息、異?;厮菪畔㈩愋?/p>

有哪些常見上下文管理器?

打開文件

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

拆分了解

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

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

file:可以理解為資源對象

執行順序

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

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

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

自定義上下文管理器

其實有兩種方式

基于類實現上下文管理器

只需要給對象添加一個 __enter__ 和一個 __exit__ 方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
class Resource:
    def __init__(self, name):
        self.name = name
        print("== 初始化方法 ==")
 
    def __enter__(self):
        print(f"** 進入上下文管理器自動調用:name is {self.name}")
        # 可以返回任意類型的值
        return {"name": self.name}
 
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"## 退出上下文管理器自動調用:", sys.exc_info(), exc_type, exc_val, exc_tb)
        if exc_tb is None:
            print("沒有異常時關閉資源")
        else:
            print("遇到異常時關閉資源")

通過 with 來調用該上下文管理器

也稱為:使用 with ... as ... 管理資源

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

console 輸出結果

== 初始化方法 ==
** 進入上下文管理器自動調用:name is 小菠蘿
{'name': '小菠蘿'}
## 退出上下文管理器自動調用: (None, None, None) None None None
沒有異常時關閉資源

__exit__() 方法的三個參數值都是 None

with 代碼塊拋出異常

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

console 輸出結果

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

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

總結

  •  無論 with 代碼塊是否有異常,最終都會自動調用 __exit__() 方法
  • 當拋出異常時,__exit__() 默認返回 None,會重新拋出異常到外面,讓 with ... as ... 以外的代碼來處理異常
  • 反之,如果返回 True,就會忽略異常,不再對異常進行處理

__exit__() 返回 True

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"## 退出上下文管理器自動調用:", sys.exc_info(), exc_type, exc_val, exc_tb)
        if exc_tb is None:
            print("沒有異常時關閉資源")
        else:
            print("遇到異常時關閉資源")
            return True
 
 
# 再次運行
with Resource("異常小菠蘿") as r:
    print('[with代碼塊] 拋出異常之前的代碼')
    raise Exception
    print('[with代碼塊] 拋出異常之后的代碼')

console 輸出結果

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

不再拋出異常

基于生成器實現上下文管理器

通過裝飾器 contextlib.contextmanager,來定義自己所需的基于生成器的上下文管理器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from contextlib import contextmanager
@contextmanager
def file_manager(name, mode):
    try:
        # 1、打開文件
        file = open(name, mode)
        # 2、返回文件資源對象
        yield file
    finally:
        # 3、關閉文件
        file.close()
with file_manager('a.txt', 'w') as file:
    print(file)
    file.write('hello world')

函數 file_manager() 就是一個生成器

當執行 with as 語句時,獲取文件資源對象,生成器暫停執行,返回文件資源對象并賦值給 file

當 with 語句執行完后,生成器繼續執行剩余代碼,關閉文件,釋放資源

總結

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

 with 語句的教程

http://m.ythuaji.com.cn/article/220256.html

以上就是Python編程ContextManager上下文管理器講解的詳細內容,更多關于Python編程Context Manager的資料請關注服務器之家其它相關文章!

原文鏈接:https://blog.csdn.net/qq_33801641/article/details/120500590

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 男人机机桶女人 | 日韩综合网 | 呜嗯啊野战h呻吟男男双性 污小说在线阅读 | 欧美高清免费一级在线 | 日本中文字幕在线精品 | 欧美精选欧美极品 | 激情另类国内一区二区视频 | 九九热只有精品 | 高清在线观看mv的网址免费 | 色天天综合网色鬼综合 | 国内精品 大秀视频 日韩精品 | 婷婷网址| 大肚孕妇的高h辣文 | 美女扒开两腿露出尿口的视频 | avtt天堂在线| 五月丁香啪啪. | 亚洲精品一区波多野结衣 | 亚洲精品久久久久69影院 | 亚洲系列国产精品制服丝袜第 | 国内亚州视频在线观看 | 精品久久久噜噜噜久久久app | 国语自产自拍秒拍在线视频 | 34看网片午夜理 | 欧美人xxxxxbbbb | 亚洲欧美在线观看首页 | 天美影视文化传媒mv免费 | 继攵催眠女乱h调教 | 国产欧美日韩在线观看精品 | 欧美日韩国产精品自在自线 | 美女口述又粗又大感觉 | 麻生希无码 | 欧美最猛性xxxxx短视频 | 午夜欧美精品久久久久久久 | 精品视频一区二区 | 青青草国产一区二区三区 | 亚洲欧美精品天堂久久综合一区 | 四虎国产视频 | 国产资源免费观看 | 青青在线香蕉国产精品 | 4hc44四虎永久地址链接 | 欧美人shou交在线播放 |