Python with语句和上下文管理器

Python with语句和上下文管理器

Python中的with语句和上下文管理器,是从2.5版本开始加入到Python语法中的。它能够让你的代码可读性更强并且错误更少。

一、with语法:

基本语法格式:

with EXPR as VAR:
	BLOCK

2.1:普通栗子:

举个文件写入时的栗子,看简单看一下try、except、else、finally执行的顺序:

try:
    f = open('test.txt', 'w')
    print('__执行:try__')

# 捕捉异常
except KeyError:
    print('__执行:except__')

else:
    f.write('—往文件里面写内容咯')
    print('__执行:else__')

finally:
    f.close()
    print('__无论以上发生了什么, 都会走到这里!__')

# 输出结果:
__执行:try__
__执行:else__
__无论以上发生了什么, 都会走到这里!__

以上栗子可以看出,try中的代码执行后,如果没有发生异常,那么会执行else中的代码,最后会执行finally,如果try中代码抛出了异常,那么执行顺序是怎样的呢?

try:
    f = open('test.txt', 'w')
    print('__执行:try__')

    # 自定义抛出一个异常
    raise KeyError

# 捕捉异常
except KeyError:
    print('__执行:except__')

else:
    f.write('—往文件里面写内容咯')
    print('__执行:else__')

finally:
    f.close()
    print('__无论以上发生了什么, 都会走到这里!__')

# 输出结果:
__执行:try__
__执行:except__
__无论以上发生了什么, 都会走到这里!__

以上结果可以看出,在try中代码抛出了异常,那么会走except中的代码,不会走else中的代码,最后也会走finally中的代码。

有没有简单的写法呢?这样写一坨肯定不符合Python的优雅。

2.2:使用with栗子:

with open('text.txt', 'w') as f:
    f.write('-往文件里面开始写内容咯-')

解释用法:with关键字,后面的open方法的返回值赋值给变量f,当离开with代码块的时候,系统会自动调用f.close()方法,with的作用和使用try,finally语句是一样的,下面来看看它的原理。

二、上下文管理简单介绍:

上下文管理器指的是在一段代码执行之前执行一段代码,做一些预处理工作,执行之后在执行一段代码,做一些清理工作,比如:

1.文件操作:打开文件进行读写、读写完后将文件进行关闭。

2.数据库操作:操作之前需要连接数据库,操作之后关闭连接数据库。

3.Socket操作:操作之前创建连接,操作之后关闭连接。

扫描二维码关注公众号,回复: 6781684 查看本文章

等等…

创建连接是一种非常昂贵的资源,不要无限的创建而不是去释放

简单的说,上下文管理器内部实现__ enter__ 和 __ exit __ 方法的对象都可以称为上下文管理器,上下文管理对象可以使用with关键字

举个栗子:

class WriteFile(object):

    def __init__(self, file_name, method):
        self.file_name = file_name
        self.method = method

    def __enter__(self):
        print('__执行enter方法__')
        self.f = open(self.file_name, self.method)
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('__执行exit方法__')
        self.f.close()


with WriteFile('test.txt', 'w') as f:
    f.write('往文件里面写数据哦')

# 输出结果:
__执行enter方法__
__执行exit方法__

__ enter __ 方法返回资源对象,就是open()方法打开那个文件对象, __ exit __ 方法处理一些释放的工作

1.调用__ enter __ 方法,执行一些预处理工作

2.as f 也可以省略,如果不省略,将 __ enter __ 方法的返回值赋值给 f

3.执行f.write()代码块

4.调用 __ exit __ 方法,有三个参数, exc_type, exc_val, exc_tb,若代码块发生异常并退出,那么分别对应异常的type、value 和 traceback。否则三个参数全为None

5.__ exit __ 方法的返回值可以为True或者False,如果为True,那么表示异常被忽视,相当于进行了try-except操作,如果为False,异常会被重新raise

因为WriteFile类实现上下文管理器,所以我们可以使用with语句

三、使用contextlib库:

Python提供内置的contextlib库,使上下文管理器更加容易使用。

简单理解:通过yield将函数分割成两部分,yield之前语句在 __ enter __ 方法中执行,yield之后的语句在 __ exit __ 方法中执行,yield 后面的值是函数的返回值

from contextlib import contextmanager


@contextmanager
def write_file(file_name, method):

    f = open(file_name, method)  # 执行 __enter__ 方法
    yield f  # 将f返回
    f.close()  # 执行 __exit__ 方法


with write_file('test.txt', 'w') as f:
    
    # f.write() 调用该write()方法
    f.write('往文件里面写东西咯!')

猜你喜欢

转载自blog.csdn.net/Fe_cow/article/details/94744932
今日推荐