Python语言实践分析 -- With语句

概述

使用C++的人往往对其中的资源释放即析构由很深的印象,其本质是将资源的释放与变量的析构函数相结合,利用语言保证的析构函数的执行的确定性来进行资源清理。在Python中有与之类似的一种机制,即是With语句。
With语句作用于上下文管理器对象中,其使用方法如下:

with open('temp','w') as f:
    f.write('a') #针对f进行操作
f.write('b')

结果:

Traceback (most recent call last):
  ......
      f.write('b')
ValueError: I/O operation on closed file.

原理

with <表达式> [as <变量名>]:
    <with语句块>

With语句语法如上,其执行过程如下:
1. 执行表达式,返回一个上下文管理器对象
2. 加载上下文管理对象的__exit__方法供后面使用
3. 调用上下文管理对象的__enter__方法
4. 如设置目标对象,将返回值赋值给目标对象
5. 执行with块中的代码块
6. 正常结束,使用None参数调用__exit__方法
7. 异常结束,则调用__exit__(exception_type, exception_value, traceback),如果__exit__返回true,则往下继续执行,如__exit__返回false,则异常重新抛出

因此如果需要自己实现上下文管理器对象,只需要实现_exit__enter_方法即可。

class TestContext(object):

    def __exit__(self, exception_type, exception_value, traceback):
        print('exit')
        return True

    def __enter__(self):
        print('enter')

with TestContext():
    print('...')

结果:

enter
...
exit

嵌套

With支持同时多个上下文管理器对象,其实质与嵌套With语句相似。

with exp1 as a, exp2 as b:
    pass
# 相当于
with exp1 as a:
    with exp2 as b:
        pass

contextlib

标准库中有contextlib模块,其可以通过yield实现上下文管理器对象。

import contextlib

@contextlib.contextmanager
def work():
    print('First part!')
    yield
    print('last part!')

with work():
    print('middle part')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值