不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • python基础

    • 01.列表
    • 02.字符串
    • 03.字典
    • 04.集合
    • 05.进程
    • 06.线程
    • 07.协程
    • 08.select、poll、epoll
    • 09.装饰器
    • 10.生成器和迭代器
    • 11.面向对象
    • 12.深浅拷贝
    • 13.垃圾回收
    • 14.上下文管理
      • 01.上下文管理
      • 02.上下文管理原理
        • 2.1 with语句原理
        • 2.2 代码实现
        • 2.3 异常处理
    • 15.网络七层
    • 16.高阶函数
    • 17.次重点
  • python模块

  • django

  • flask

  • SYL

  • Celery

  • 微服务

  • python
  • python基础
xiaonaiqiang
2021-02-11
目录

14.上下文管理

# 01.上下文管理

  • 1、什么是with语句

    • with是一种上下文管理协议,目的在于从流程图中把 try,except 和finally 关键字和资源分配释放相关代码统统去掉,简化try….except….finlally的处理流程。
    • 所以使用with处理的对象必须有enter()和exit()这两个方法
      • 1)with通过enter方法初始化(enter方法在语句体执行之前进入运行)
      • 然后在exit中做善后以及处理异常(exit()方法在语句体执行完毕退出后运行)
  • 2、with语句使用场景

    • with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源
    • 比如文件使用后自动关闭、线程中锁的自动获取和释放等。
  • 3、with处理文件操作的实例

with open('/etc/passwd') as f:
  for line in f:
    print(line)

# 这段代码的作用:打开一个文件,如果一切正常,把文件对象赋值给f,然后用迭代器遍历文件中每一行,当完成时,关闭文件;
# 而无论在这段代码的任何地方,如果发生异常,此时文件仍会被关闭。
1
2
3
4
5
6
# -*- coding: utf-8 -*-
with open('a2.py',encoding='utf8') as f:
    print( f.readlines())

try:
    f = open('a2.py',encoding='utf8')
    f.read()
except Exception as e:
    print(print(e))
finally:
    f.close()
1
2
3
4
5
6
7
8
9
10
11

# 02.上下文管理原理

# 2.1 with语句原理

  • with实际上是python中的关键字,它可以开启一个对象的上下文管理器协议

  • 实际上,在文件操作时,并不是不需要写文件的关闭,而是文件的关闭操作在 with 的上下文管理器中的协议方法里已经写好了

  • 当文件操作执行完成后, with语句会自动调用上下文管理器里的关闭语句来关闭文件资源。

  • 简单来说,就是在一个类里,实现了__enter__和__exit__的方法,这个类的实例就是一个上下文管理器.

# 2.2 代码实现

  • __enter__: 进入对象的上下文管理器调用的方法,会返回一个值,并赋值给as关键词之后的变量

  • __exit__:退出对象的上下文管理器调用的方法,定义了处理结束后要做的事情,比如文件的关闭,socket的断开等

#自定义一个上下文管理器,模拟with文件操作
class MyOpen(object):
    def __init__(self,path,mode,encoding='utf8'):
        # 记录要操作的文件路径和模式
        self.__path = path
        self.__mode = mode
        self.__encoding = encoding
        # 打开文件
        self.__handle = open(self.__path,self.__mode,encoding=self.__encoding)
    def __enter__(self):
        print('代码执行到了__enter__......')
        # 返回打开的文件对象引用, 用来给  as 后的变量f赋值
        return self.__handle
 
    # 退出方法中,用来实现善后处理工作
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('代码执行到了__exit__......')      
        self.__handle.close()
 
# a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
with MyOpen('test.txt','a+') as f:
    # 创建写入文件
    f.write("Hello Python!!!")
    print("文件写入成功")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  • 运行结果
代码执行到了__enter__......
文件写入成功
代码执行到了__exit__......
1
2
3

# 2.3 异常处理

  • 异常可以在__exit__ 进行捕获并由你自己决定如何处理,是抛出还是不抛出。
  • 在__exit__ 里返回 True(没有return 就默认为 return False),就相当于告诉 Python解释器,这个异常我们已经捕获了,不需要再往外抛了。
# 编写两个数做除法的程序,然后给除数穿入0
class MyCount(object):
    # 接收两个参数
    def __init__(self, x, y):
        self.__x = x
        self.__y = y

    # 返回一个地址(实质是被as后的变量接收),实例对象就会执行MyCount中的方法:div()
    def __enter__(self):
        print('代码执行到了__enter__......')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("代码执行到了__exit__......")
        if exc_type == None:
            print('程序没问题')
        else:
            print('程序有问题,如果你能你看懂,问题如下:')
            print('Type: ', exc_type)
            print('Value:', exc_val)
            print('TreacBack:', exc_tb)

        # 返回值决定了捕获的异常是否继续向外抛出
        # 如果是 False 那么就会继续向外抛出,程序会看到系统提示的异常信息
        # 如果是 True 不会向外抛出,程序看不到系统提示信息,只能看到else中的输出
        return True

    def div(self):
        print("代码执行到了除法div")
        return self.__x / self.__y


with MyCount(1, 0) as mc:
    mc.div()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  • 执行结果
代码执行到了__enter__......
代码执行到了除法div
代码执行到了__exit__......
程序有问题,如果你能你看懂,问题如下:
Type:  <class 'ZeroDivisionError'>
Value: division by zero
TreacBack: <traceback object at 0x000001A7CC28D0C8>
1
2
3
4
5
6
7
上次更新: 2024/3/13 15:35:10
13.垃圾回收
15.网络七层

← 13.垃圾回收 15.网络七层→

最近更新
01
04.数组双指针排序_子数组
03-25
02
08.动态规划
03-25
03
06.回溯算法
03-25
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式