在Python2.5中with關鍵字被加入。它是用來取代try…except…finally…的模式。
#with語句使用於對資源進行存取的場合。確保使用過程中不管是否發生異常,都會執行必要的「清理」操作,並釋放資源。例如文件使用後自動關閉,線程中鎖的自動獲取和釋放。
with EXPR [ as VAR ]: BLOCK 简单说明: 1,EXPR可以是任意表达式。 2,as VAR是可选的。 3,BLOCK是with语句的语句体
加上說明:
1,計算EXPR,並取得一個上下文管理器。
2,上下文管理器的exit()方法被保存起來用於之後的呼叫。
3,呼叫上下文管理器的enter()方法
4,如果with表達式包含as VAR,那麼EXPR的回傳值被賦值給VAR。
5,執行BLOCK中的表達式
6,調永上下文管理器的exit()方法。如果BLOCK的執行過程中發生了一個異常導致程式退出,那麼異常中的type、value、和traceback(也就是sys.exc_info()的回傳值)將會作為參數傳遞給exit()方法,然後異常拋出在控制台。否則將傳遞三個None值。
mgr = (EXPR) exit = type(mgr).__exit__ # 这里没有执行 value = type(mgr).__enter__(mgr) exc = True try: try: VAR = value # 如果有 as VAR BLOCK except: exc = False if not exit(mgr, *sys.exc_info()): raise finally: if exc: exit(mgr, None, None, None)
注意:
1,如果上下文管理器中沒有enter()或exit()中的任意一個方法,那麼解釋器會拋出一個AttributeError.
2,在BLOCK中發生異常後,如果exit()方法回傳一個可以被看成是True的值,那麼這個例外就不會被拋出,後面的程式碼就會繼續執行。
class my_name: def __enter__(self): print("调用__enter__()方法") return "xiaoke" def __exit__(self, type, value, trace): print("调用__exit__()方法") def get_name(): return my_name() with get_name() as name: print("my name is :", name) # 结果如下: # 调用__enter__()方法 # my name is : xiaoke # 调用__exit__()方法
class number: # with语句执行的时候调用 def __enter__(self): print("调用_enter_()方法") return self # with语句执行完毕,结束的时候调用 def __exit__(self, type, value, trace): print("type:", type) print("value:", value) print("trace:", trace) # 当有异常的时候,那么就不会有返回值 def do_number(self): num = 10 / 0 return num + 100with number()as result: res = result.do_number() print(res) # 结果如下: # 调用_enter_()方法 # type: <class 'ZeropisionError'> # value: pision by zero # trace: <traceback object at 0x00000224182AE388> # Traceback (most recent call last): # File "E:/pycharmProject/Test49.py", line 56, in <module> # res = result.do_number() # File "E:/pycharmProject/Test49.py", line 51, in do_number # num = 10 / 0 # ZeropisionError: pision by zero
官网代码:import asyncio async def coro(name, lock): print('coro {}: waiting for lock'.format(name)) async with lock: print('coro {}: holding the lock'.format(name)) await asyncio.sleep(1) print('coro {}: releasing the lock'.format(name)) loop = asyncio.get_event_loop() lock = asyncio.Lock() coros = asyncio.gather(coro(1, lock), coro(2, lock))try: loop.run_until_complete(coros)finally: loop.close()
輸出程式碼:
coro 1: waiting for lock coro 1: holding the lock coro 2: waiting for lock coro 1: releasing the lock coro 2: holding the lock coro 2: releasing the lock
文章參考資料如下:1,官網:https://www. python.org/dev/peps/pep-0343/2
以上是如何理解Python中with語句的詳細內容。更多資訊請關注PHP中文網其他相關文章!