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. 打造高效 VIM

    删除空行 删除1到10行的空行 :1,10g/^$/d 命令行快捷命令 Bang(!)命令 上一条命令:!! 使用上一条命令的所有参数:!* 使用上一条命令的最后一个参数:!$ 使用上一条命令中除了最 ...

  2. postman 接口测试(一)

    一.postman 应用场景 开发接口快速的调用接口,以便调试 方便的调用接口,通过不同的参数去测试接口的输出 这些接口调用时需要保存下来的反复运行的 在运行中如果有断言(检查点 <预期 和现实 ...

  3. 在RecyclerView中集成QQ汽泡二

    上次已经将GooView集成到RecyclerView当中了[http://www.cnblogs.com/webor2006/p/7787511.html],但是目前还有很多问题,下面先来运行看一下 ...

  4. 在RecyclerView中集成QQ汽泡一

    上次已经实现了QQ汽泡的自定义View的效果[http://www.cnblogs.com/webor2006/p/7726174.html],接着再将它应用到列表当中,这样才算得上跟QQ的效果匹配, ...

  5. 转 shell中的多进程【并发】

    原文地址https://bbs.51cto.com/thread-1104907-1-1.html 根据我个人的理解, 所谓的多进程 只不过是将多个任务放到后台执行而已,很多人都用到过,所以现在讲的主 ...

  6. UVa10474 Where is the Marble?(排序sort)

    今天开始学STL,这是书上的一道例题,主要是用了sort函数和lower_bound函数,挺容易理解的. lower_bound的作用是查找“大于或等于x的第一个位置”. 需要注意的是,不要忘记alg ...

  7. BZOJ2238 Mst[最小生成树+树剖+线段树]

    跑一遍mst.对于非mst上的边,显然删掉不影响. 如果删边在树上,相当于这时剩下两个连通块.可以证明要重新构成mst只需要再加一条连接两个连通块的最小边,不会证,yy一下,因为原来连通块连的边权和已 ...

  8. 如何用eclipse进行jar文件打包?

    直接导出runnable jar,如下图所示: 然后选择导出runnable jar: 关于library handling部分的解释如下: (1)Extract required libraries ...

  9. IOS下图片不能显示问题的解决办法

    最近遇到这样一个问题,在HTML5手机页面中,直接给<img>标签设置宽高,即便图片路径正常,在IOS真机下也是无法显示的,而在安卓以及浏览器的模拟真机上都是正常显示的,这是为什么呢? h ...

  10. 放大镜如何用js

    例如: let imgs = { small: ["imgA_1.jpg", "imgB_1.jpg", "imgC_1.jpg"], mi ...