python with语句执行过程

with语句用于执行一个使用context manager定义的方法,它允许常用的try…catch…finally使用模式被得封装更易重用。

with_stmt ::= “with” with_item (“,” with_item)* “:” suite
with_item ::= expression [“as” target]

例如:

with open('a.txt') as f:
        print(f.readlines())

with语句对一个’item’的执行过程如下:
1. 环境表达式(context expression)(在with_item中给出的表达式)被计算,得到一个环境管理器(context manager)
2. Context manager的exit()方法被加载,用于后面的步骤。
3. Context manager的enter()方法被调用。
4. 如果with表达式中包含有target,就把enter()方法的返回值赋给它。
5. suite被执行。(例如上面的print(f.readlines()))
6. Context manager的exit()方法被调用。如果一个异常在suite执行过程中发生了,它的类型、值和trackback会作为参数传进exit()。否则,exit()的三个参数都设为None。
如果suite因为异常而退出,并且exit()方法的返回值是false,异常就会被再次抛出。如果返回值为true,那么异常就会被抑制(suppressed),并且继续执行with语句之后的语句。
如果suite因为不是异常的任何其他原因退出,exit()的返回值会被忽略,并且以这种退出方式应该使用的方式执行下去。(大概是这个意思)
原文:If the suite was exited for any reason other than an exception, the return value from exit() is ignored, and execution proceeds at the normal location for the kind of exit that was taken.

如果有超过一个with_item,context manager按照有多个with语句嵌套的方式执行下去:

with A() as a, B() as b:
    suite

等价于

with A() as a:
    with B() as b:
        suite

也可以参考:
PEP 0343 - The “with” statement
The specification, background, and examples for the Python with statement.

Reference: https://docs.python.org/3/reference/compound_stmts.html#with

你可能感兴趣的:(python)