一文带你搞懂Python上下文管理器

 更新时间:2022年06月23日 15:57:44   作者:曲鸟  
这篇文章主要为大家介绍了Python上下文管理器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

一、什么是上下文管理器

我们在处理文件的时候经常看到下面这样的代码,它即是上下文管理器:

with open('test.txt', encoding='utf-8') as f:
    print(f.readlines())

它的含义是打开当前目录下的test.txt文件并打印它里面的内容,与下面的代码效果是一样的:

f = open('test.txt', encoding='utf-8')
print(f.readlines())
f.close()

对比两种写法能够发现,使用with自动执行了f.close()(关闭文件)的这步操作,能够少写一点代码。

那这样的上下文管理器是怎么实现的,下面为你讲解。

二、如何实现上下文管理器

1. 通过类实现

如果要实现上面open的上下文管理器功能,我们可以通过创建一个类,并添加__enter____exit__方法即可,如下面的代码所示:

class DiyOpen(object):

    def __init__(self, filename, **kwargs):
        self.f = open(filename, **kwargs)

    def __enter__(self):
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('关闭文件')
        self.f.close()


with DiyOpen('test.txt', encoding='utf-8') as f:
    print(f.readlines())

输出结果

['第一行\n', '第二行\n', '第三行']
关闭文件

可以看到在我们打印出文件内容后,自动执行了关闭文件的操作。

__enter____exit__的含义是什么,__exit__后面的exc_type, exc_val, exc_tb又是什么意思呢?

1)_enter_

__enter__相对来说好理解的多,当出现with语句时,它就会被触发,有返回值时,会把返回值赋值给as声明的变量,也就是我们上面的as f中的f。

2)_exit_

__exit__是在with执行完成后自动执行的,他后面的参数含义如下:

  • exc_type:异常类型
  • exc_val:异常原因e
  • xc_tb:堆栈追踪信息

当with中执行的代码报错时,除了不继续执行with包含的代码外,还会将报错信息放入上面的三个参数中,例如下面的代码:

class DiyOpen(object):

    def __init__(self, filename, **kwargs):
        self.f = open(filename, **kwargs)

    def __enter__(self):
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        self.f.close()


with DiyOpen('test.txt', encoding='utf-8') as f:
    print(f.no())

输出结果

<class 'AttributeError'>
'_io.TextIOWrapper' object has no attribute 'no'
<traceback object at 0x000002A34B834900>

需要注意的是:

  • 我们可以手动指定__exit__的返回值为True让它不报错。
  • 没有异常信息时,上面的三个参数值都会为None

2. 通过contextlib实现

Python内置了contextlib这个模块用于实现上下文管理器,它是通过生成器yield实现的,这个模块让我们不必再创建类和__enter__和__exit__了。

通过contextlib实现open功能的代码如下:

from contextlib import contextmanager

@contextmanager
def diy_open(filename, **kwargs):
    f = open(filename, **kwargs)  # __init__
    try:
        yield f  # __enter__
    finally:  # __exit__
        f.close()

with diy_open('test.txt', encoding='utf-8') as f:
    print(f.readlines())

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • 对python同一个文件夹里面不同.py文件的交叉引用方法详解

    对python同一个文件夹里面不同.py文件的交叉引用方法详解

    今天小编就为大家分享一篇对python同一个文件夹里面不同.py文件的交叉引用方法详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • Python3.7 dataclass使用指南小结

    Python3.7 dataclass使用指南小结

    本文将带你走进python3.7的新特性dataclass,通过本文你将学会dataclass的使用并避免踏入某些陷阱。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • 浅谈matplotlib默认字体设置探索

    浅谈matplotlib默认字体设置探索

    这篇文章主要介绍了matplotlib默认字体设置探索,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • Python中实现地图可视化的方法小结

    Python中实现地图可视化的方法小结

    Python提供了多个强大的库,如Folium、Matplotlib、Geopandas等,使得创建漂亮而具有信息量的地图变得简单而灵活,本文将详细介绍如何使用这些库绘制漂亮的地图,感兴趣的可以了解下
    2023-12-12
  • pandas函数isnull的具体使用

    pandas函数isnull的具体使用

    本文主要介绍了pandas函数isnull的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • python matplotlib绘制三维图的示例

    python matplotlib绘制三维图的示例

    这篇文章主要介绍了matplotlib绘制三维图的示例,帮助大家更好的利用python matplotlib绘制图像,感兴趣的朋友可以了解下
    2020-09-09
  • pytorch 准备、训练和测试自己的图片数据的方法

    pytorch 准备、训练和测试自己的图片数据的方法

    这篇文章主要介绍了pytorch 准备、训练和测试自己的图片数据的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • Python3中使用urllib的方法详解(header,代理,超时,认证,异常处理)

    Python3中使用urllib的方法详解(header,代理,超时,认证,异常处理)

    这篇文章整理了一些关于urllib使用中的一些关于header,代理,超时,认证,异常处理处理方法,对大家学习python具有一定的参考借鉴价值,有需要的朋友们下面来一起看看吧。
    2016-09-09
  • python事件驱动event实现详解

    python事件驱动event实现详解

    这篇文章主要为大家详细介绍了python事件驱动event实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • Python字符集和字符编码详情

    Python字符集和字符编码详情

    这篇文章主要介绍了Python字符集和字符编码详情,Python中的字符串是通过unicode来表示的,在底层对应的结构体是PyUnicodeObject,但是具体为什么呢?带着疑问一起学习下面文章内容吧
    2022-05-05

最新评论