python上下文管理器

python上下文管理器

  • 1. 前言
  • 2. 先谈 'with'
  • 3. 上下文管理器
  • 5. 装饰器contextmanager

1. 前言

偶然间认识了with,但它是什么意思,有什么用?

对于这些很是模糊,下面我们就细细看来。

2. 先谈 ‘with’

  1. 刚学习文件操作时的做法

这是初学时最基础的方法,打开文件,读(写)内容,关闭文件。

# 1.打开文件
file = open("D:\\record.txt","r",encoding='utf-8')  # 打开的文件区分大小写
# 2.读取文件的内容
text = file.read()
print(text)
# 3.关闭文件
file.close()
  1. 有个小问题

打个比方:我在打开文件后,要进行读(写)的操作,刚好在这个过程中出现了异常 导致后面的代码不能继续执行,也就是说文件无法关闭(文件资源无法释放)。

我想到了,之前学习过try

file = open("D:\\record.txt","r",encoding='utf-8')
try:
    f = file.read()
finally:
    file.close()

注意: 无论是否发生异常,它都会去执行finally 关闭文件。

  1. 针对问题2做的升级

with会自动调用close()

with open('a.txt') as f:
    x = f.read()

3. 上下文管理器

一个类只要实现  __enter__ 和 __exit__ 方法都可称之为上下文管理器。

__enter__:with执行前调用,returnopen的文件对象
__exit__ :with执行完被调用

步骤:

  1. 首先会调用__init__方法
  2. 调用__enter__方法,return返回要打开的对象,它会通过as赋值给变量f
  3. 执行with里面的语句
  4. 最后执行__exit__方法
class File():
    def __init__(self, name, mode):
        print('第1 __init__')
        self.name = name  # 文件路径
        self.mode = mode  # 打开方式

    def __enter__(self):
        print('第2 __enter__')
        self.file = open(self.name, self.mode)
        return self.file

    # def __exit__(self, *args):
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('第5 __exit__')
        self.file.close()


with File('a.txt', 'r') as f:
    print('第3 with')
    print('第4', f.read())
打印结果:

第1 __init__
第2 __enter__
第3 with4 1231231235 __exit__

5. 装饰器contextmanager

contextmanager使得上下文管理器更加简单。

from contextlib import contextmanager


@contextmanager
def fun_test(path, mode):
    print('1')
    file = open(path, mode)
    print('2')
    yield file
    print('3')
    file.close()


with fun_test('a.txt', 'r') as f:
    print('4')
    print(f.read())

r需要我们自己进行异常处理,如下代码添加try-finally

from contextlib import contextmanager


@contextmanager
def fun_test(path, mode):
    try:
        print('1')
        file = open(path, mode)
        print('2')
        yield file
        print('3')
    finally:
        file.close()


with fun_test('a.txt', 'r') as f:
    print('4')
    print(f.read())
1
2
4
123123123
3

1. 调用 fun_test方法,开始从函数上面向下执行
2. 执行yield  返回file,它的返回值给了f
3. 执行with语句
4.yield后面继续执行

你可能感兴趣的:(Python,python,开发语言)