Python 的with关键字

看别人的代码时,with关键字经常会出现,博主决定梳理一下with以及python中上下文(context)的概念

1. 上下文管理器概念

Context Manager指的是python在执行一段代码前后,做的一些预处理和后处理,使得代码块运行处于一个小的环境(surrounding),出了这个小环境之后,资源释放,环境中的各种配置也失效。

例如在打开文件需要关闭,连接数据库后需要关闭连接。很多优雅第三方库也会利用上下文使得对象进入特定的某种状态。

2. with关键字

with的基本用法如下:

with EXPR as VAR:
BLOCK

其中发生了一系列过程:

  1. EXPR语句被执行,得到ContextManager
  2. 调用ContextManager.__enter__方法
  3. 如果有as VAR,则ContextManager.__enter__的返回值赋给VAR,否则就不管返回值
  4. 执行BLOCK,如果有VAR被用到,就和普通变量一样
  5. 调用ContextManager.__exit__方法
    • __exit__有三个参数:type, value, traceback,BLOCK出异常时会得到对应值,正常情况就都为None
    • __exit__返回值为True表示BLOCK中出现的异常可以忽略,False表示需要raise

3. 例子

3.1 资源操作:

class CustomOpen:
def __init__(self, filename: str):
self.__filename = filename
self.__handler = None def __enter__(self):
print("enter......")
self.__handler = open(self.__filename)
return self.__handler def __exit__(self, exc_type, exc_val, exc_tb):
print("exit...", exc_type, exc_val, exc_tb)
if self.__handler is not None:
self.__handler.close()
return True with CustomOpen("hello.txt") as f:
print(f.read())

运行结果:

enter......
hello world
exit... None None None

3.2 状态维护

class CustomBrain:
def __init__(self):
self.__status = "normal" def say(self):
if self.__status == "normal":
print("You're a great man")
elif self.__status == "special":
print("You are a very outstanding person ") def __enter__(self):
self.__status = "special" def __exit__(self, exc_type, exc_val, exc_tb):
self.__status = "normal" brain = CustomBrain()
brain.say() # 普通状态 # 可以通过上下文维护一些状态
with brain:
brain.say() # 特殊状态 brain.say() # 普通状态

运行结果:

You're a great man
You are a very outstanding person
You're a great man

4. 使用contextlib简化编写

python内置的标准库contextlib可以是的代码书写更加简洁,本质是一样的。比较有用的是contextlib.contextmanager这个装饰器,被装饰的函数在yield的前面相当于__enter__,yield的后面相当于__exit__,yield本身的返回值赋给as后的变量

所以第一个示例可以这么写:

from contextlib import contextmanager

@contextmanager
def custom_open(filename: str):
print("enter......")
handler = open(filename) yield handler print("exit...")
handler.close() with custom_open("hello.txt") as f:
print(f.read())

还是优雅了许多~

Python 的with关键字的更多相关文章

  1. Python中的关键字的用法

    Python有哪些关键字 -Python常用的关键字 and, del, from, not, while, as, elif, global, or, with, assert, else, if, ...

  2. python的标识符&&关键字

    和Java语言一样,python也有标识符和关键字.那么,你是否知道python的关键字呢?一起先从标识符了解python吧. 什么是标识符? 标识符,开发人员在开发过程中自定义的一些符号和名称. 标 ...

  3. python中super关键字的用法

    http://python.jobbole.com/86787/ class A: def __init__(self):    print "enter A"    print ...

  4. python正则提取关键字

    python使用正则表达式提取关键字 import sys reload(sys) sys.setdefaultencoding("utf-8") import re ss = & ...

  5. python 位置参数和关键字参数 *args **kwargs

    #!/usr/bin/env pythondef foo(*args,**kwargs): print('args: {0}'.format(args)) print('kwargs {0}'.for ...

  6. python进阶之关键字和运算符触发魔法方法

    前言 python有众多的魔法方法,它们会在满足某种条件下触发执行,掌握好魔法方法的使用,可以加快程序的运行效率,同时减少逻辑调用. 关键字与魔法方法 python的一些魔法方法是关键字触发的,即py ...

  7. python开发_python关键字

    python3.3.2中的关键字如下: The following identifiers are used as reserved words, or keywords of the languag ...

  8. python语言(四)关键字参数、内置函数、导入第三方模块、OS模块、时间模块

    一.可变参数 定义函数时,有时候我们不确定调用的时候会传递多少个参数(不传参也可以).此时,可用包裹(packing)位置参数(*args),或者包裹关键字参数(**kwargs),来进行参数传递,会 ...

  9. 怎样查看python的所有关键字

    关键字是python中具有特定功能的一组词汇, 这些词汇不能用作变量名, 一般会有高亮提示, code时请小心. python的关键字其实也是python的语法核心, 掌握了所有python关键字的用 ...

随机推荐

  1. 使用hbuilder打包时,调用地图和相机

    <template> <div class="comCon"> <!-- 你是头部区域的内容 --> <headback class=&q ...

  2. php--常见算法3

    <?php function leijia($number){ $arr=[]; for($i=1;$i<=$number;$i++) { for($j=1;$j<=$number; ...

  3. Windows问题

    常用工具 DisplayFusion 官网 电脑分屏,V9.4 Pro 破解版 问题解决 Win64位注册表导入方法 64位Windows操作系统注册表不同于32位Windows操作系统,Win64 ...

  4. Redis03——Redis架构

    Redis架构 1.1.问题 redis是单线程,单实例,为什么并发那么多,依旧很快呢? 回答:因为调用了系统内核的epoll 1.2.Linux的早期版本 Linux有Linux kernal,我们 ...

  5. Codeforce Round #424

    A 略 B 略 C: 先对Ai数列预处理前缀和 然后把Bi的每个都加一次 最终得到的结果为ans[sum]++; 最后如果有一个ans[sum]>=k即满足所有K个条件就输出(注意!!前缀和要进 ...

  6. POI读取Excel如何判断行为空

    public static boolean isRowEmpty(Row row) { for (int c = row.getFirstCellNum(); c < row.getLastCe ...

  7. 查看python包的安装目录

    步骤二: 如果是从python 的command line 里面查看,可以使用如下命令(python 3.x) import sys print(sys.path)   1 2

  8. DevExpress Blazor组件全新来袭!增强Data Grid、TreeView API

    点击获取DevExpress v19.1.7最新完整版试用下载 DevExpress UI for Blazor即将在最新的v19.1.8中可用,此次更新发布包括DevExpress Blazor组件 ...

  9. 记录微信小程序里自带 时间格式 工具

    微信小程序里面自己给了一个时间工具,是用来记录log日志,感觉可以记录下来,所以拿来自己用,以此记录: 直接传入 日期对象 进入 formatTime //得到下面格式的时间格式2017/07/22 ...

  10. 【Python之路】特别篇--五句话搞定JavaScript作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...