python上下文管理器

DAY 23. python上下文管理器

Python 的 with 語句支持通過上下文管理器所定義的運行時上下文這一概念。 此對象的實現使用了一對專門方法,允許用戶自定義類來定義運行時上下文,在語句體被執行前進入該上下文,并在語句執行完畢時退出該上下文:

實現了__enter__()__exit__(exc_type, exc_val, exc_tb)方法的對象就是上下文管理器,上下文管理器可以被with支持。

class Demo:def __init__(self):print("init")def __enter__(self):print("enter")def __exit__(self, exc_type, exc_val, exc_tb):print("exit")if __name__ == '__main__':demo = Demo()with demo:print("with")

__enter__()的返回值將會賦值給與with配套使用的as后面的變量,__exit__()如果返回True會忽略with中拋出的所有異常,返回False(默認)會向下傳遞異常,三個參數exc_type, exc_val, exc_tb分別表示捕捉到的異常類型,異常值,回溯信息,沒有異常為None。其行為類似于try,finally語句,不管有沒有產生異常,exit一定會被執行。

class Demo:def __init__(self):print("init")def __enter__(self):print("enter")return selfdef __exit__(self, exc_type, exc_val, exc_tb):print(exc_type, exc_val, exc_tb)print("exit")if __name__ == '__main__':demo = Demo()with demo as d:print(d)raise IOError("主動拋出異常")print("with")

結果:

Traceback (most recent call last):
initFile "E:/桌面文件/筆記/Note/Python/總結/code/DAY23/DAY23_1.py", line 18, in <module>
enterraise IOError("主動拋出異常")
<__main__.Demo object at 0x00000243B4005908>
OSError: 主動拋出異常
<class 'OSError'> 主動拋出異常 <traceback object at 0x00000243BAEDD048>
exit

__exit__() return True后的運行結果

init
enter
<__main__.Demo object at 0x00000183AFDA11D0>
<class 'OSError'> 主動拋出異常 <traceback object at 0x00000183B6E6F908>
exit

傳入的異常絕對不應當被顯式地重新引發 —— 相反地,此方法應當返回一個假值以表明方法已成功完成并且不希望屏蔽被引發的異常.
這允許上下文管理代碼方便地檢測 __exit__() 方法是否確實已失敗。

generator與contextlib.contextmanager

Python 的 generatorcontextlib.contextmanager 裝飾器提供了實現這些協議的便捷方式。 如果使用 contextlib.contextmanager 裝飾器來裝飾一個生成器函數,它將返回一個實現了必要的 __enter__() and __exit__() 方法的上下文管理器,而不再是由未經裝飾的生成器函數所產生的迭代器。

contextlib.contextmanager 是一個裝飾器,它可以不用定義類或__enter__()__exit__(exc_type, exc_val, exc_tb)方法而產生一個上下文管理器,被裝飾的函數必須是一個生成器對象,并且這個迭代器只能yield出一個對象,它會被綁定到with語句as后面的變量上

from contextlib import contextmanager@contextmanager
def my_open(path: str, mode: str):# 之所以之捕捉了yield語句的異常,是因為我們只希望如果with語句塊中# 產生了異常,也可以確保close()被執行,至于open可能拋出的異常,我們希望它# 能夠向下傳遞。fp = open(path, mode)try:yield ffinally:print("close the file")fp.close()if __name__ == '__main__':with my_open('01.txt', 'w') as fp:raise OSErrorfp.write("111")

代碼執行順序是:

  1. 執行yield之前的語句
  2. yield調用后執行with中的代碼塊
  3. 最后執行yield之后的語句

closing()

closing()是contextlib中的一個方法,用來把一個不是上下文對象的方法變成上下文對象,也是用contextmanage實現的,一個官方的栗子

from contextlib import closing
from urllib.request import urlopenwith closing(urlopen('http://www.python.org')) as page:for line in page:print(line)

不用顯式調用page.close()也能確保執行

suppress()

可以選擇禁止一個或多個異常

if __name__ == '__main__':with suppress(OSError):with my_open('01.txt', 'r') as fp:# 拋出的這個異常會被忽略raise OSErrorfp.write("111")

redirect_stdout/redirect_stderr

重定向輸入輸出

# 將輸出重定向到文件from contextlib import redirect_stdoutpath = "test/test.txt"with open(path,"w") as fobj:with redirect_stdout(fobj):help(open)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457544.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457544.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457544.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

勾股定理python思路_趣叮咚編程數學揭秘:為什么勾股定理a+b=c?

我們都知道&#xff1a;三角形3個外角之和360度可是誰知道為什么等于360度呢&#xff1f;其實利用編程制作動圖演繹了解啦&#xff1a;那勾股定理abc又是為什么呢&#xff1f;還有很多有趣的數學公式都可以演繹&#xff1a;圓的面積公式、圓周長...通過動圖演繹原來晦澀難懂的定…

System.InvalidOperationException : 不應有 Response xmlns=''。

xml如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <Response version"2"><datacash_reference>4700203048783633</datacash_reference><information>Failed to identify the card scheme of the supp…

Navicat Premium連接SQL Server

Navicat Premium連接SQL Server 步驟&#xff1a; 激活SQL Server 服務配置SQL Server網絡配置連接SQL Server 激活SQLServer服務 直接搜索 計算機管理 點 服務和應用程序&#xff0c; 點 SQL Server配置管理器&#xff0c; 雙擊第一個SQL Server服務 不出意外的話&#xf…

mysql 單標遞歸_MySql8 WITH RECURSIVE遞歸查詢父子集的方法

背景開發過程中遇到類似評論的功能是&#xff0c;需要時用查詢所有評論的子集。不同數據庫中實現方式也不同&#xff0c;本文使用Mysql數據庫&#xff0c;版本為8.0Oracle數據庫中可使用START [Param] CONNECT BY PRIORMysql 中需要使用 WITH RECURSIVE需求找到name為張三的孩子…

processon完全裝逼指南

一、引言 作為一名IT從業者&#xff0c;不僅要有扎實的知識儲備&#xff0c;出色的業務能力&#xff0c;還需要具備一定的軟實力。軟實力體現在具體事務的處理能力&#xff0c;包括溝通&#xff0c;協作&#xff0c;團隊領導&#xff0c;問題的解決方案等&#xff0c;這些能力在…

mysql在空閑8小時之后會斷開連接(默認情況)

調試程序的過程發現&#xff0c;在mysql連接空閑一定時間&#xff08;默認8小時&#xff09;之后會斷開連接&#xff0c;需要重新連接&#xff0c;也引發我對重連機制的思考。轉載于:https://www.cnblogs.com/ppzbty/p/5707576.html

selector多路復用_多路復用器Selector

Unix系統有五種IO模型分別是阻塞IO(blocking IO)&#xff0c;非阻塞IO( non-blocking IO)&#xff0c;IO多路復用(IO multiplexing)&#xff0c;信號驅動(SIGIO/Signal IO)和異步IO(Asynchronous IO)。而IO多路復用通常有select&#xff0c;poll&#xff0c;epoll&#xff0c;k…

解決svn log顯示no author,no date的方法之一

只要把svnserve.conf中的anon-access read 的read 改為none&#xff0c;也不需要重啟svnserve就行 sh-4.1# grep "none" /var/www/html/svn/pro/conf/svnserve.conf ### and "none". The sample settings below are the defaults. anon-access none轉載…

REST framework 權限管理源碼分析

REST framework 權限管理源碼分析 同認證一樣&#xff0c;dispatch()作為入口&#xff0c;從self.initial(request, *args, **kwargs)進入initial() def initial(self, request, *args, **kwargs):# .......# 用戶認證self.perform_authentication(request)# 權限控制self.che…

解決larave-dompdf中文字體顯示問題

0、使用MPDF dompdf個人感覺沒有那么好用&#xff0c;最終的生產環境使用的是MPDF&#xff0c;github上有文檔說明。如果你堅持使用&#xff0c;下面是解決辦法。可以明確的說&#xff0c;中文亂碼是可以解決的。 1、安裝laravel-dompdf依賴。 Packagist&#xff1a;https://pa…

mfc程序轉化為qt_小峰的QT學習筆記

我的專業是輸電線路&#xff0c;上個學期&#xff0c;我們開了一門架空線路設計基礎的課&#xff0c;當時有一個大作業是計算線路的比載&#xff0c;臨界檔距&#xff0c;弧垂最低點和安裝曲線。恰逢一門結課考試結束&#xff0c;大作業ddl快到&#xff0c;我和另外兩個同專業的…

MS SQL的存儲過程

-- -- Author: -- Create date: 2016-07-01 -- Description: 注冊信息 -- ALTER PROCEDURE [dbo].[sp_MebUser_Register]( UserType INT, MobileNumber VARCHAR(11), MobileCode VARCHAR(50), LoginPwd VARCHAR(50), PayPwd VARCHAR(50), PlateNumber VARCHAR(20), UserTr…

mysql 中 all any some 用法

-- 建表語句 CREATE TABLE score(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20),SUBJECT VARCHAR(20),score INT);-- 添加數據 INSERT INTO score VALUES (NULL,張三,語文,81), (NULL,張三,數學,75), (NULL,李四,語文,76), (NULL,李四,數學,90), (NULL,王五,語文,81), (…

REST framework 用戶認證源碼

REST 用戶認證源碼 在Django中&#xff0c;從URL調度器中過來的HTTPRequest會傳遞給disatch(),使用REST后也一樣 # REST的dispatch def dispatch(self, request, *args, **kwargs):""".dispatch() is pretty much the same as Djangos regular dispatch,but w…

scrapyd部署_如何通過 Scrapyd + ScrapydWeb 簡單高效地部署和監控分布式爬蟲項目

來自 Scrapy 官方賬號的推薦需求分析初級用戶&#xff1a;只有一臺開發主機能夠通過 Scrapyd-client 打包和部署 Scrapy 爬蟲項目&#xff0c;以及通過 Scrapyd JSON API 來控制爬蟲&#xff0c;感覺 命令行操作太麻煩 &#xff0c;希望能夠通過瀏覽器直接部署和運行項目專業用…

最長上升子序列 (LIS算法(nlong(n)))

設 A[t]表示序列中的第t個數&#xff0c;F[t]表示從1到t這一段中以t結尾的最長上升子序列的長度&#xff0c;初始時設F [t] 0(t 1, 2, ..., len(A))。則有動態規劃方程&#xff1a;F[t] max{1, F[j] 1} (j 1, 2, ..., t - 1, 且A[j] < A[t])。 現在&#xff0c;我們仔細…

牛頓插值--python實現

from tabulate import tabulate import sympy""" 牛頓插值法 """class NewtonInterpolation:def __init__(self, x: list, y: list):self.Xi = xself

css搖曳的_HTML5+CSS3實現樹被風吹動搖晃

1新建html文檔。2書寫hmtl代碼。3書寫css代碼。.trunk, .trunk div { background: #136086; width: 100px; height: 10px; position: absolute; left: 50%; top: 70%; margin-left: -10px; -webkit-animation-name: rot; animation-name: rot; -webkit-animation-duration: 2.0…

素數路(prime)

素數路(prime) 題目描述 已知一個四位的素數&#xff0c;要求每次修改其中的一位&#xff0c;并且要保證修改的結果還是一個素數&#xff0c;還不能出現前導零。你要找到一個修改數最少的方案&#xff0c;得到我們所需要的素數。 例如把1033變到8179&#xff0c;這里是一個最短…

python多線程單核_002_Python多線程相當于單核多線程的論證

很多人都說python多線程是假的多線程!下面進行論證解釋:一、我們先明確一個概念&#xff0c;全局解釋器鎖(GIL)Python代碼的執行由Python虛擬機(解釋器)來控制。Python在設計之初就考慮要在主循環中&#xff0c;同時只有一個線程在執行&#xff0c;就像單CPU的系統中運行多個進…