詳解Playwright中 With as 的用法
大家在做playwright自動(dòng)化測(cè)試時(shí),一定會(huì)遇到下面的寫法
with sync_playwright() as p:
自動(dòng)化代碼
很多同學(xué)可能只是按照這種寫法來編寫項(xiàng)目的自動(dòng)化測(cè)試代碼,對(duì)于具體細(xì)節(jié)可能并不了解,今天我來結(jié)合playwright講解一下 Python中的 with ... as 用法。建議大家拷貝文檔中的腳本實(shí)際運(yùn)行一下,學(xué)習(xí)的效果會(huì)更好!
with ... as 概述
在Python中,with語句用于異常處理,使代碼更簡(jiǎn)潔、可讀性更強(qiáng)。它簡(jiǎn)化了文件流等公共資源的管理?;A(chǔ)表達(dá)式如下:
with 表達(dá)式a [as target]:
代碼塊
在上面的表達(dá)式中, [as target] 中的部分可以省略。其中,target 參數(shù)用于指定一個(gè)變量,該語句會(huì)將表達(dá)式a指定的結(jié)果保存到該變量中,我們可以通過with ... as 操作上下文對(duì)象。具體實(shí)現(xiàn)方法是為一個(gè)類定義__enter__和__exit__兩個(gè)函數(shù)。
with 表達(dá)式a [as target] 的執(zhí)行過程是首先執(zhí)行__enter__ 函數(shù),它的返回值會(huì)賦給as后面的target,如果不寫as target,返回值會(huì)被忽略;然后開始執(zhí)行代碼塊中的語句;最后不論執(zhí)行成功或者失敗都會(huì)執(zhí)行__exit__函數(shù),為了更好的理解其運(yùn)行原理,請(qǐng)參考下面的詳細(xì)代碼解釋:
with obj as f:
f.method(...)
# obj 表示一個(gè)對(duì)象(或是一個(gè)表達(dá)式, 結(jié)果為一個(gè)對(duì)象)
# 調(diào)用 obj 對(duì)象的 __enter__ 方法, 返回值賦值給 as 右邊的變量 f,即: f = obj.__enter__()
# 執(zhí)行 with 代碼塊中的代碼 f.method(...)
# 執(zhí)行完 with 代碼塊中的代碼后, 無論是否發(fā)生異常, 調(diào)用 obj 的 __exit__ 方法,即: obj.__exit__(...)
上面的過程其實(shí)等價(jià)于
obj = ...
f = obj.__enter__()
try:
# f.method(...)
finally:
obj.__exit__(...)
注意這里是 try finally 而不是 try except?。?!
with ... as 實(shí)例
下面舉一個(gè)例子,讓大家了解一下,with真正強(qiáng)大之處——它可以處理異常。
class WithSample:
def __enter__(self):
print("__enter__()")
return self
def __exit__(self, type, value, trace):
print( "__exit__()")
print( "type:", type) #輸出type值
print( "value:", value) #輸出value值
print("trace:", trace) #輸出trace值
def do_something(self):
num = 1 / 0 #模擬異常出現(xiàn)
return num + 1
with WithSample() as sample:
sample.do_something()
print("---- end ----") #這句話很有用!
輸出:
Traceback (most recent call last):
File "C:/Users/Administrator/PycharmProjects/playwright/demo2.py", line 19, in <module>
sample.do_something()
File "C:/Users/Administrator/PycharmProjects/playwright/demo2.py", line 13, in do_something
num = 1 / 0
ZeroDivisionError: division by zero
__enter__()
__exit__()
type: <class 'ZeroDivisionError'>
value: division by zero
trace: <traceback object at 0x000002C7FE590288>
從上面代碼我們得知,在with后面的代碼塊會(huì)首先執(zhí)行__enter__方法的值,然后在拋出任何異常時(shí),_exit__方法都會(huì)被執(zhí)行,并輸出type、value和trace的值。
一個(gè)容易被忽略的問題
這里需要注意一下,代碼后面的語句 print("---- end ----") 并沒有執(zhí)行,這就說明程序發(fā)生了異常,執(zhí)行了__exit__ 以后,程序就退出了!為什么呢?還記得前面講過的知識(shí)點(diǎn)嗎?
這里劃重點(diǎn)!with obj as f 等價(jià)于try ... finally,而不是 try ... except... finally
最后補(bǔ)充一句!如果想捕獲 with as 的異常,我們?nèi)匀恍枰褂胻ry ... except... finally
try:
with api as f:
#business as usual
except Exception as e:
#handle exception