日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Python中with上下文管理協議的作用及用法_python

作者:king_weng ? 更新時間: 2022-05-21 編程語言

1、簡介

? ? ? ?with是從Python2.5引入的一個新的語法,它是一種上下文管理協議,目的在于從流程圖中把 try,except 和finally 關鍵字和資源分配釋放相關代碼統統去掉,簡化try…except…finlally的處理流程。

? ? ? ?那我們先理解一下try…except…finally語句是干啥的。實際上,try…except語句和try…finally語句是兩種語句,用于不同的場景。但是當二者結合在一起時,可以“實現穩定性和靈活性更好的設計”。

2、try… except語句

? ? ? ?用于處理程序執行過程中的異常情況,比如語法錯誤、從未定義變量上取值等等,也就是一些python程序本身引發的異常、報錯。而try… except語句就是為了防止一些報錯影響你的程序繼續運行,就用try語句把它們抓出來(捕獲)。

(1)try…except的標準格式

try: ?
? ? ## normal block ?
except A: ?
? ? ## exc A block ?
except: ?
? ? ## exc other block ?
else: ?

(2)程序執行流程

–>執行normal block
–>發現有A錯誤,執行 exc A block(即處理異常)
–>結束
如果沒有A錯誤呢?
–>執行normal block
–>發現B錯誤,開始尋找匹配B的異常處理方法,發現A,跳過,發現except others(即except:),執行exc other block
–>結束
如果沒有錯誤呢?
–>執行normal block
–>全程沒有錯誤,跳入else 執行noError block
–>結束

(3)異常分類

? ? ? ?except后面還能跟表達式的! 所謂的表達式,就是錯誤的定義。也就是說,我們可以捕捉一些我們想要捕捉的異常。而不是什么異常都報出來。

異常分兩類:

  • python標準異常
  • 自定義異常

(a)Python標準異常

? ? ? Python標準異常包括NameError(未聲明/初始化對象,沒有屬性),MemoryError內存溢出錯誤等錯誤,

詳細python標準異常詳見:

異常名稱 描述
BaseException 所有異常的基類
SystemExit 解釋器請求退出
KeyboardInterrupt 用戶中斷執行(通常是輸入^C)
Exception 常規錯誤的基類
StopIteration 迭代器沒有更多的值
GeneratorExit 生成器(generator)發生異常來通知退出
StandardError 所有的內建標準異常的基類
ArithmeticError 所有數值計算錯誤的基類
FloatingPointError 浮點計算錯誤
OverflowError 數值運算超出最大限制
ZeroDivisionError 除(或取模)零 (所有數據類型)
AssertionError 斷言語句失敗
AttributeError 對象沒有這個屬性
EOFError 沒有內建輸入,到達EOF 標記
EnvironmentError 操作系統錯誤的基類
IOError 輸入/輸出操作失敗
OSError 操作系統錯誤
WindowsError 系統調用失敗
ImportError 導入模塊/對象失敗
LookupError 無效數據查詢的基類
IndexError 序列中沒有此索引(index)
KeyError 映射中沒有這個鍵
MemoryError 內存溢出錯誤(對于Python 解釋器不是致命的)
NameError 未聲明/初始化對象 (沒有屬性)
UnboundLocalError 訪問未初始化的本地變量
ReferenceError 弱引用(Weak reference)試圖訪問已經垃圾回收了的對象
RuntimeError 一般的運行時錯誤
NotImplementedError 尚未實現的方法
SyntaxError Python 語法錯誤
IndentationError 縮進錯誤
TabError Tab 和空格混用
SystemError 一般的解釋器系統錯誤
TypeError 對類型無效的操作
ValueError 傳入無效的參數
UnicodeError Unicode 相關的錯誤
UnicodeDecodeError Unicode 解碼時的錯誤
UnicodeEncodeError Unicode 編碼時錯誤
UnicodeTranslateError Unicode 轉換時錯誤
Warning 警告的基類
DeprecationWarning 關于被棄用的特征的警告
FutureWarning 關于構造將來語義會有改變的警告
OverflowWarning 舊的關于自動提升為長整型(long)的警告
PendingDeprecationWarning 關于特性將會被廢棄的警告
RuntimeWarning 可疑的運行時行為(runtime behavior)的警告
SyntaxWarning 可疑的語法的警告
UserWarning 用戶代碼生成的警告

例:

 ? try:
? ? ? ? a = 1 / 2
? ? ? ? print(a)
? ? ? ? print(m) ?# 此處拋出python標準異常
? ? ? ? b = 1 / 0 ?# 此后的語句不執行
? ? ? ? print(b)
? ? ? ? c = 2 / 1
? ? ? ? print(c)
? ? except NameError:
? ? ? ? print("Ops!!")
? ? except ZeroDivisionError:
? ? ? ? print("Wrong math!!")
? ? except:
? ? ? ? print("Error")

輸出:

3、try…finallly語句

? ? ? ?try…finallly語句用于無論執行過程中有沒有異常,都要執行清場工作。

格式:

try: ?
? ? execution block ?##正常執行模塊 ?
except A: ?
? ? exc A block ##發生A錯誤時執行 ?
except B: ?
? ? exc B block ##發生B錯誤時執行 ?
except: ?
? ? other block ##發生除了A,B錯誤以外的其他錯誤時執行 ?
else: ?
? ? if no exception, jump to here ##沒有錯誤時執行 ?
finally: ?
final block ?##總是執行 ?

tips: 注意順序不能亂,否則會有語法錯誤。如果用else就必須有except,否則會有語法錯誤。

例: ??

 ?try:
? ? ? ? a = 1 / 2
? ? ? ? print(a)
? ? ? ? print(m) ?# 拋出NameError異常
? ? ? ? b = 1 / 0
? ? ? ? print(b)
? ? ? ? c = 2 / 1
? ? ? ? print(c)
? ? except NameError:
? ? ? ? print("Ops!!") ?# 捕獲到異常
? ? except ZeroDivisionError:
? ? ? ? print("Wrong math!!")
? ? except:
? ? ? ? print("Error")
? ? else:
? ? ? ? print("No error! yeah!")
? ? finally: ?# 是否異常都執行該代碼塊
? ? ? ? print("finally!")

輸出:

4、with…as語句

(1)With語句的基本語法

? ? ? ?with通過__enter__方法初始化,然后在__exit__中做善后以及處理異常。其中__enter__()方法在語句體(with語句包裹起來的代碼塊)執行之前進入運行,__exit__()方法在語句體執行完畢退出后運行。

? ? ? ?with 語句適用于對資源進行訪問的場合,確保不管使用過程中是否發生異常都會執行必要的“清理”操作,釋放資源,比如文件使用后自動關閉、線程中鎖的自動獲取和釋放等。

With語句的基本語法格式:

with expression [as target]:
with-block ?
  • expression:是一個需要執行的表達式;
  • target:是一個變量或者元組,存儲的是expression表達式執行返回的結果,可選參數。

(2)with語句原理

  • 上下文管理協議(Context Management Protocol):包含方法 __enter__()和__exit__(),支持該協議的對象要實現這兩個方法。
  • 上下文管理器(Context Manager):支持上下文管理協議的對象,這種對象實現了__enter__()和__exit__()方法。上下文管理器定義執行with語句時要建立的運行時上下文,負責執行with語句塊上下文中的進入與退出操作。通常使用with語句調用上下文管理器,也可以通過直接調用其方法來使用。

例:執行過程

with EXPR as VAR:
? ? BLOCK

(1)執行EXPR,生成上下文管理器context_manager

(2)獲取上下文管理器的__exit()__方法,并保存起來用于之后的調用;

(3)調用上下文管理器的__enter__()方法;如果使用了as子句,則將__enter__()方法的返回值賦值給as子句中的VAR;

(4)執行BLOCK中的表達式;

(5)不管是否執行過程中是否發生了異常,執行上下文管理器的__exit__()方法,__exit__()方法負責執行“清理”工作,如釋放資源等。如果執行過程中沒有出現異常,或者語句體中執行了語句break/continue/return,則以None作為參數調用__exit__(None, None, None);如果執行過程中出現異常,則使用sys.exc_info得到的異常信息為參數調用__exit__(exc_type, exc_value, exc_traceback);

(6)出現異常時,如果__exit__(type, value, traceback)返回False,則會重新拋出異常,讓with之外的語句邏輯來處理異常,這也是通用做法;如果返回True,則忽略異常,不再對異常進行處理。

這個和try finally函數有什么關系呢?其實,這樣的過程等價于:

try: ?
? ? 執行 __enter__的內容 ?
? ? 執行 with_block. ?
finally: ?
? ? 執行 __exit__內容 ?

例:

class Sample(object):
?
? ? def __init__(self):
? ? ? ? print("__init__")
?
? ? def __enter__(self):
? ? ? ? print("__enter__")
?
? ? def __exit__(self, types, values, trace):
? ? ? ? print("type:", types)
? ? ? ? print("value:", values)
? ? ? ? print("trace:", trace)
?
?
def get_sample():
? ? return Sample()
?
?
if __name__ == '__main__':
? ? # get_data()
? ? with get_sample() as sample:
? ? ? ? print("Sample:", sample)

輸出:

原文鏈接:https://blog.csdn.net/King_weng/article/details/123554031

欄目分類
最近更新