视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
如何理解Python中with语句
2020-11-27 14:22:30 责编:小采
文档


Num02–>with语句的作用

with语句使用于对资源进行访问的场合。确保使用过程中不管是否发生异常,都会执行必要的“清理”操作,并释放资源。比如文件使用后自动关闭,线程中锁的自动获取和释放。

Num03–>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的值,那么这个异常就不会被抛出,后面的代码会继续执行。

Num04–>没有异常案例

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__()方法

Num05–>有异常案例

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

Num06–>在Python3.5中加入,协程中使用with,要加入async关键字

官网代码: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

下载本文
显示全文
专题