在我们使用Python的时候,常使用到如下的代码块:

# 文件读取
with open(file, 'r') as f:# CODE BLOCK ## 梯度计算
with tf.GradientTape() as g:# CODE BLOCK #

在很多场景中,使用with语句来可以让我们可以更好地来管理资源和简化代码,它可以看做是对try/finally模式的简化。它原理上是利用了上下文管理器,下文简要介绍将对其执行原理和自定义的方法。

概念

上下文管理协议(Context Management Protocol)

包含方法 __enter__()__exit__() ,支持该协议的对象要实现这两个方法。

上下文管理器(Context Manager)

支持上下文管理协议的对象,这种对象必须实现 __enter__()__exit__() 方法。
上下文管理器定义执行with语句时要建立的运行时上下文,负责执行with语句块上下文中的进入与退出操作。
通常使用with语句调用上下文管理器,也可以通过直接调用其方法来使用。

  • __enter__()

    • with语句执行时,先获取上下文管理器对象,随后调用其 __enter__()
    • 若有 as var 语句,则将返回值赋给变量var
    • 可以返回上下文管理器对象本身,也可以是其他相关对象
  • __exit__()
    • 带有三个参数 exc_type, exc_val, exc_tb
    • 若上下文管理器对象执行无异常,则三个参数均为 None
    • 若发生异常,则三个参数分别为 异常类型,异常值和tracback信息

原理

#   EXP: 表达式
#   VAR: 变量名,[as VAR][可选]
# BlOCK: 代码块with EXP as VAR:BLOCK

with语句原理
  1. 执行代码时,先执行 EXPR 语句,生成上下文管理器对象 context_manager;
  2. 获取上下文管理器的 __exit()__ 方法,并保存起来用于之后的调用;
  3. 调用上下文管理器的 __enter__() 方法,且可将返回值赋给as语句变量;
  4. 执行BLOCK中的表达式;
  5. 不管是否执行过程中是否发生了异常,执行上下文管理器的 __exit__() 方法, 执行“清理”工作,如释放资源等。
    1. 如果执行过程中没有出现异常,或者语句体中执行了语句 break / continue / return ,则以 None 作为参数调用 __exit__(None, None, None)
    2. 如果执行过程中出现异常,则使用sys.exc_info得到的异常信息为参数调用 __exit__(exc_type, exc_value, exc_traceback)
  6. 出现异常时,如果 __exit__(type, value, traceback) 返回 False ,则会重新抛出异常,让with之外的语句逻辑来处理异常,这也是通用做法;如果返回True,则忽略异常,不再对异常进行处理。

自定义上下文管理器

  • 它使代码更简练,可以简化try/finally模式
  • 当代码异常产生时,__exit__() 会执行清理工作
  • 可以对软件系统中的资源进行管理,比如数据库连接、共享资源的访问控制等
# coding = utf-8# 上下文管理器类
class TestWith(object):def __init__(self):passdef __enter__(self):"""进入with语句的时候被调用并将返回值赋给as语句的变量名"""print('__enter__')return "var"def __exit__(self, exc_type, exc_val, exc_tb):"""离开with的时候被with调用"""print('__exit__')return True# with后面必须跟一个上下文管理器
# 如果使用了as,则是把上下文管理器的 __enter__() 方法的返回值赋值给 target
# target 可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)
if __name__ = 'main':with TestWith() as var:print(var)# 运行结果
'''
__enter__
var
__exit__
'''

本例仅对应代码正常执行的流程,其他特殊情况不再一一列举,有兴趣可单独实验。

参考

浅谈 Python 的 with 语句
Python中with用法详解
Python中with使用

mysql with as 用法_Python之图解with语句相关推荐

  1. mysql delete limit用法_你习惯delete语句后带上limit吗

    声明:本文基于MySQL讲解. 先不说习惯不习惯的,很多人也许会惊讶:还可以这样操作?其实,大家对这个操作比较陌生,也不奇怪.因为,学海无涯呀~ 语法 这个用法的详细语法是这样的:delete fro ...

  2. python的for语句用法_python中list循环语句用法实例

    本文实例讲述了python中list循环语句用法.分享给大家供大家参考.具体用法分析如下: Python 的强大特性之一就是其对 list 的解析,它提供一种紧凑的方法,可以通过对 list 中的每个 ...

  3. python中多重if语句用法_Python多分支if语句的使用

    注意:if语句代码是从上往下执行的,当执行到满足条件的语句时,代码会停止往下执行 注意:if语句后面要加上冒号 score = int (input("score:")) if s ...

  4. python中if else语句用法_Python if else条件语句详解

    前面我们看到的代码都是顺序执行的,也就是先执行第1条语句,然后是第2条.第3条--一直到最后一条语句,这称为顺序结构. 但是对于很多情况,顺序结构的代码是远远不够的,比如一个程序限制了只能成年人使用, ...

  5. MySQL:讨人喜欢的 MySQL replace into 用法(insert into 的增强版)

    讨人喜欢的 MySQL replace into 用法(insert into 的增强版) 在向表中插入数据的时候,经常遇到这样的情况:1. 首先判断数据是否存在: 2. 如果不存在,则插入:3.如果 ...

  6. 【node】express中mysql的基本用法、连接池的使用、事务的回滚

    [node]express中mysql的基本用法.连接池的使用 安装mysql包 mysql的配置信息 mysql基本操作 查询mysql并渲染数据 mysql插入操作 首先在html页面写上< ...

  7. Linux下Mysql的查询用法

    Linux下Mysql的查询用法 一.Mysql的delete删除语法 1.删除数据库 2.删除数据库的表 二.查询数据 1.基本查询 2.条件查询 三.数据库插入数据 1.创建新表 2.插入数据 四 ...

  8. MySQL replace into 用法

    MySQL replace into 用法(insert into 的增强版) 在向表中插入数据的时候,经常遇到这样的情况:1. 首先判断数据是否存在: 2. 如果不存在,则插入:3.如果存在,则更新 ...

  9. Mysql临时表的用法 - 51CTO.COM

    Mysql临时表的用法 - 51CTO.COM Mysql临时表我们经常会用到,下面就为您详细介绍Mysql临时表的用法,供您参考,如果您对此方面感兴趣的话,不妨一看. 当工作在非常大的表上时,你可能 ...

最新文章

  1. python3 hmac算法简介
  2. hdu4923 f(A,B)分段处理
  3. 电气论文:梯级水电站调度优化建模(文末有程序下载链接)
  4. Android多线程之同步锁的使用
  5. IoTSharp部署教程-Sqlite分表篇
  6. 《.NET Core 和前后端那些事儿》技术交流活动纪实
  7. oracle 有计划任务吗,oracle计划任务的问题
  8. 基于用户投票的排名算法(一):Delicious和Hacker News
  9. SAP License:SAP中的文本管理
  10. 9.2 定义和浏览翻译
  11. spark处理大数据实例
  12. 关于OSPF的区域划分规则
  13. CMOS MIPI EOT 学习 基于Zynq高速串行CMOS接口的设计与实现
  14. Win10+VS2019编译Jpeg源码时缺少win32.mak文件的内容
  15. Java8的其它 新特性(笔记二十四)
  16. 魔兽世界服务器显示新,《魔兽世界》怀旧服再开新服,背后的原因竟然是!
  17. 找不到工作的测试员一大把,大厂却招不到优秀软件测试员?高薪难寻测试工程师。
  18. 互联网公司平均薪资Top8 , 阿里勇夺第一。
  19. 水仙花数的实现(python)
  20. MySQL数据库锁介绍

热门文章

  1. easyuefi无法安装只能在基于_SOLIDWORKS2018安装时VC2015安装失败的解决方法
  2. mllib协同过滤 java实现_协同过滤(ALS)算法介绍及Spark MLlib调用实例(Scala/Java/Python)...
  3. java core 生成路径_core文件生成和路径设置
  4. mysql默认字符集和排序_MySQL字符集和排序规则
  5. JAVA实现inotify一样的功能_WPF实现INotifyPropertyChanged
  6. Win7旗舰版打不开任务管理器怎么办
  7. Win7系统电脑休眠后无法唤醒的解决方法
  8. java基础学习笔记(一)
  9. android创建空文件,ADT 更新 eclipse srclayout 文件夹创建时候为空
  10. Java核心类库篇7——多线程