Python上下文管理器的语法

本文介绍了Python的上下文管理器,包括with语句的使用和__enter__、__exit__方法的功能。上下文管理器简化了资源的获取和释放,如文件操作,确保在发生异常时也能正确关闭。通过例子展示了如何自定义上下文管理器,以及在进入和退出时__enter__和__exit__方法的执行情况。
摘要由CSDN通过智能技术生成

考虑一个常见的用例——打开文件,通过使用Python内置的open函数打开文件,打开一个文件后,关闭文件就是你的责任了,如下所示:

try:
    f = open('path/to/filename', 'r')
    content = f.read()
finally:
    f.close()

使用finally子句确保无论发生什么,文件都将被关闭。

with语句

如何使用上下文管理器完成同样的功能——打开文件并确保被正确关闭?上下文管理器在Python2.5中引入,并新增了对应的关键字:with,使用with语句可以进入上下文管理器。

而Python的内置函数open同样可以作为上下文管理器使用,以下的代码与上面的效果相同:

with open('path/to/filename', 'r') as f:
    content = f.read()

从本质上讲,实际上是with语句对其后的代码进行求值(也就是open函数),该表达式会返回一个对象,该对象包含两个特殊的方法:__enter__和__exit__,__enter__方法的返回值会赋值给as关键字后面的变量。

需要注意的是,在with后的表达式的返回结果没有被赋值给任何所谓的变量,而只是其对应的__enter__方法的返回值被赋值给as后的变量。

简单性是使用上下文管理器的重要原因,更重要的是,记住用于异常处理和清理的代码有时会非常复杂,并且在不同的地方应用也非常麻烦。与装饰器相同的是,使用上下文管理器的关键原因在于避免代码重复。

__enter__和__exit__方法

记住,with语句的表达式的作用仅仅是返回一个遵从特定协议的对象,该对象必须定义的有__enter__和__exit__方法,当该对象被返回时,其对应的__enter__方法立即执行,如果有as语句,__enter__的返回值会被赋给as后面的变量。

往往__enter__方法内进行一些预处理或者说一些配置,比如连接数据库、打开文件返回相应的连接对象或文件描述符,__enter__方法除了self参数外,不接受其他的任何参数。

__exit__方法往往在退出上下文管理器时被执行,除了self参数外,带有3个位置参数:异常类型、异常实例、回溯,这三个参数在没有异常发生时,都会被设为None,如果有异常时,则会被填充。

考虑下面一个简单的上下文管理器实现:

class ContextManager(object):
    def __init__(self) -> None:
        self.entered = False

    def __enter__(self):
        self.entered = True

    def __exit__(self, ex_type, ex_instance, traceback):
        self.entered = False

该上下文管理器只是在进入时把entered变量置为True,退出时置为False,下面我们创建一个ContextManager对象:

>>> cm = ContextManager()
>>> cm.entered
False

可以看到此时cm的entered的值为False,进一步我们使用这个上下文管理器对象cm:

>>> with cm:
...   cm.entered
...
True

当在被with语句包装的代码块里也即进入到上下文管理器,entered的值变成了True,这就是__enter__方法的作用,在进入时被调用。而当离开了with语句代码块的作用域,也即离开上下文管理器时,__exit__方法被执行,entered会再次被置为False:

>>> cm.entered
False
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值