日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python 上下文管理器、 else 块、@contextmanager

發(fā)布時間:2024/7/5 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 上下文管理器、 else 块、@contextmanager 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 1. else
    • 2. with上下文管理器
    • 3. contextlib模塊實用工具
    • 4. @contextmanager 裝飾器

learn from 《流暢的python》

1. else

  • for/else、while/else 和 try/else
    前兩者 只有在 沒有被break 時,才會運行 else
    try 塊中沒有異常拋出時 才運行 else
for i in range(3):print(i) else:print("finish, no break")# finish, no breakfor i in range(3):if i == 2:breakprint(i) else:print("break")# 無輸出i = 0 while i < 3:print(i)i += 1 else:print("no break") # no breaki = 0 while i < 3:if i==2:breakprint(i)i += 1 else:print("break") # 無輸出arr = [0] try:arr[0] = 1 except:print("error") # 無輸出 else:print("no error, run else")# no error, run elsearr = [] try:arr[0] = 0 except:print("error") # error else:print("error, will not run else") # 無輸出 finally:print("finish") # finish # finally 子句中的代 碼通常用于釋放重要的資源,或者還原臨時變更的狀態(tài)

else 這么用的比較少

2. with上下文管理器

上下文管理器協(xié)議包含 __enter__ 和 __exit__ 兩個方法

  • with 語句 運行時,會在上下文管理器對象上調(diào)用 __enter__ 方法
  • with 語句 結(jié)束后,會在上下文管理器對象上調(diào)用 __exit__ 方法,以此扮 演 finally 子句的角色(釋放重要的資源,或者 還原臨時變更的狀態(tài)),如 關(guān)閉文件等
class LookingGlass:def __enter__(self): # 沒有其它的參數(shù)了import sysself.original_write = sys.stdout.writesys.stdout.write = self.reverse_writereturn 'ABCD'def reverse_write(self, text): # 反轉(zhuǎn)字符串,實現(xiàn)輸出self.original_write(text[::-1])def __exit__(self, exc_type, exc_value, traceback):# exc_type 異常類# exc_value 異常實例# traceback 對象# 在 try/finally 語句的 finally 塊中調(diào)用 sys.exc_info()# 得到的就是 __exit__ 接收的這三個參數(shù)import syssys.stdout.write = self.original_writeif exc_type is ZeroDivisionError:print('Please DO NOT divide by zero!')return Truewith LookingGlass() as what:# 進入 __enter__ 函數(shù)時返回的 ABCD 字符串存入 whatprint("Michael learning python")# nohtyp gninrael leahciMprint(what)# DCBA print("Michael learning python") # Michael learning python print(what) # ABCD manager = LookingGlass() print(manager) # <__main__.LookingGlass object at 0x00000231226F2190> string = manager.__enter__() print(string) # DCBA print(string == "ABCD") # eurT, 所有的輸出經(jīng)過管理器的 反向輸出處理了 print(string == "DCBA") # eslaF, 所有的輸出經(jīng)過管理器的 反向輸出處理了 print(manager) # >0912F62213200000x0 ta tcejbo ssalGgnikooL.__niam__< manager.__exit__(None, None, None) # 還原了正常的輸出 print(string) # ABCD

3. contextlib模塊實用工具

  • closing 如果對象 提供了 close() 方法,但沒有實現(xiàn) __enter__/__exit__ 協(xié)議,那么可以使用這個函數(shù)構(gòu)建上下文管理器
  • suppress, 構(gòu)建臨時 忽略指定異常 的上下文管理器
  • @contextmanager,裝飾器 把簡單的 生成器函數(shù) 變成 上下文管理器,這樣就不用創(chuàng)建類去實現(xiàn)管理器協(xié)議了
  • ContextDecorator,這是個基類,用于定義基于類的上下文管理器。這種上下文管理器 也能用于 裝飾函數(shù),在受管理的上下文中運行整個函數(shù)
  • ExitStack,這個上下文管理器 能進入多個 上下文管理器。with 塊結(jié)束時,ExitStack 按照后進先出的順序調(diào)用棧中各個上下文管理器的 __exit__ 方法。
    如果事先不知道 with 塊要進入 多少個上下文管理 器,可以使用這個類。例如,同時打開任意一個文件列表中的所有文件

使用最廣泛的是 @contextmanager 裝飾 器,因此要格外留心
這個裝飾器也有迷惑人的一面,因為它與迭代 無關(guān),卻要 使用 yield 語句

4. @contextmanager 裝飾器

  • @contextmanager 裝飾器能減少代碼量,因為 不用編寫一個完整的類,定義 __enter__ 和 __exit__ 方法,而 只需實現(xiàn) 有一個 yield 語句的生成器,生成想讓 __enter__ 方法返回的值
  • 在使用 @contextmanager 裝飾的生成器中,yield 語句的作用是 把函數(shù)的定義體分成兩部分:
    yield 語句前面的所有代碼在 with 塊開始時 (即解釋器調(diào)用 __enter__ 方法時)執(zhí)行
    yield 語句后面的代碼在 with 塊結(jié)束時(即調(diào)用 __exit__ 方法時)執(zhí)行
import contextlib@contextlib.contextmanager def looking_glass1():import sysoriginal_write = sys.stdout.writedef reverse_write(text):original_write(text[::-1])sys.stdout.write = reverse_writeyield 'ABCD' # 產(chǎn)出的值綁定到 as 目標(biāo)上# 執(zhí)行 with 塊代碼時,函數(shù)會在這里暫停sys.stdout.write = original_write# 控制權(quán)一旦跳出 with 塊,繼續(xù)執(zhí)行 yield 語句之后的代碼with looking_glass1() as what:print("Michael learning python")print(what) # nohtyp gninrael leahciM # DCBA print("Michael learning python") print(what) # Michael learning python # ABCD

其實,contextlib.contextmanager 裝飾器會把函數(shù)包裝成實現(xiàn) __enter__ 和 __exit__ 方法的

用于原地重寫文件的上下文管理器

import csv with inplace(csvfilename, 'r', newline='') as (infh, outfh): reader = csv.reader(infh) writer = csv.writer(outfh) for row in reader: row += ['new', 'columns'] writer.writerow(row)

inplace 函數(shù)是個上下文管理器,為同一個文件提供了兩個句柄(例中的 infh 和 outfh),以便同時讀寫同一個文件。比標(biāo)準(zhǔn)庫中的 fileinput.input 函數(shù) 易用

總結(jié)

以上是生活随笔為你收集整理的python 上下文管理器、 else 块、@contextmanager的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。