with和上下文管理器

如果你有时间阅读源码的习惯,可能会看到一些优秀的代码会出现带有with关键字的语句。

对于系统资源如文件,数据库连接,socket而言,应用程序打开这些资源并执行完业务逻辑之后,必须要做的事情就是关闭该资源。

在上篇文件中,我们读写文件操作,完毕之后,关闭文件对象。调用close方法,下面来看看如何正确的关闭一个文件。

普通版
def func():
f = open("1.txt", "w")
f.write("Python")
f.close()

这样写有一个误区,如果在调用write方法时,出现了异常无法继续执行下面代码,资源就被该程序一直占用系统资源。

进阶版
def func():
f = open("1.txt", "w")
try:
f.write("python")
except IOError:
print("oops, error")
finally:
f.close()

上面的程序我们使用异常进行了捕获,finally内代码执行关闭资源。如果需要学习异常的使用,请看下篇文章。

高级版
def func():
with open("1.txt", "r") as f:
f.write("python")

简洁优雅的写法就是使用with关键字。with的作用和使用异常捕获try/finally语句是一样的。想了解with原理,我们必须知道上下文管理器。

上下文管理器

任何实现了__enter__()__exit__()方法的对象都可以称为上下文管理器,上下文管理器对象可以使用with关键字,文件对象也实现了上下文管理器。

自定义类实现上下文管理器,示例代码:

class File():
def __init__(self, file_name, mode):
self.file_name = file_name
self.mode = mode def __enter__(self):
self.f = open(self.file_name, self.mode)
return self.f def __exit__(self, *args):
self.f.close()

enter()方法返回资源对象,这就是要打开的文件对象,exit()方法处理清除工作。因为File类实现了上下文管理器,现在就可以使用with语句了。

with File("1.txt", "w") as f:
f.write("hello, python")

这样一来,系统自动调用close方法实现关闭资源。

装饰器实现上下文管理器

Python提供了contextmanager的装饰器,更进一步简化了上下文管理器的实现方式,通过yield将函数分为两部分,yield之前的语句在__enter__()方法中执行,yield之后的语句在__exit__()执行。

from contextlib import contextmanger

@contextmanger
def my_open(path, mode):
f = open(path, mode)
yield f
f.close()

调用:

with my_open("1.txt", "w") as f:
f.write("hello, python")

本文中应用到了装饰器,异常,前面未讲到,如有需要,请看以后的文章,后续文章会讲到装饰器,下篇文章则是异常的使用。

with和上下文管理器的更多相关文章

  1. Python with语句和上下文管理器

    open("FishC.txt","w")#此处需注意如果被打开的文件中,已有内容,那么用w的方式打开,则会导致原文件内容被截断,也就是相当于被清空了,然后重新 ...

  2. django-10-中间件和上下文管理器

    <<<中间件的引入>>> 用户<->中间件<->url->视图  在app目录里面 middleware.py  (1)中间件就是一个 ...

  3. 文件操作-with和上下文管理器

    代码: # -*- coding:utf-8 -*- # 普通版 如果写入的过程中出错 则不会释放资源 def m1(): f = open("test.txt","w& ...

  4. Python之上下文管理器

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #Python之上下文管理器 #http://python.jobbole.com/82620/ #语法形式: ...

  5. python基础之上下文管理器

    前言 关于计算器运行的上下文的概念,我的理解也不是很深:按我的理解就是程序在运行之前,其所需要的资源,运行环境等都会被序列化,然后加入到CPU的任务队列中,等待调度系统分配时间片执行.下面谈谈pyth ...

  6. python with和上下文管理工具

    对于系统资源如文件.数据库连接.socket 而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源. 比如 Python 程序打开一个文件,往文件中写内容,写完之后, ...

  7. Django:之Sitemap站点地图、通用视图和上下文渲染器

    Django中自带了sitemap框架,用来生成xml文件 Django sitemap演示: sitemap很重要,可以用来通知搜索引擎页面的地址,页面的重要性,帮助站点得到比较好的收录. 开启si ...

  8. Flask 进阶session和上下文管理解析

    session的源码流程 将session放置在redis中 安装 pip install flask-session 使用 import redis from flask import Flask, ...

  9. (转)Python中的上下文管理器和Tornado对其的巧妙应用

    原文:https://www.binss.me/blog/the-context-manager-of-python-and-the-applications-in-tornado/ 上下文是什么? ...

随机推荐

  1. 2. react 简书 头部(header) 图标添加

    1. 访问 iconfont 并注册 登陆 2. 进入 iconfont 头部 图标管理->我的项目 3. 点击右边的文件夹 + 号 图标 创建我的项目 输入项目名称即可 4.在 搜索框 搜索 ...

  2. linux网络编程之shutdown() 与 close()函数详解

    linux网络编程之shutdown() 与 close()函数详解 参考TCPIP网络编程和UNP: shutdown函数不能关闭套接字,只能关闭输入和输出流,然后发送EOF,假设套接字为A,那么这 ...

  3. 028、Java中的关系运算符

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  4. (分治)输出前m大的数。。。

    描述给定一个数组包含n个元素,统计前m大的数并且把这m个数从大到小输出.输入第一行包含一个整数n,表示数组的大小.n < 100000.第二行包含n个整数,表示数组的元素,整数之间以一个空格分开 ...

  5. Golang的运算符优先级实操案例

    Golang的运算符优先级实操案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.运算符优先级案例 运算符是用来在程序运行时执行数学或逻辑运算的,在Go语言中,一个表达式可以包 ...

  6. Adapter之ArrayAdapter以及监听器设置

    前言: ArrayAdapter:支持泛型操作,最简单的一个Adapter,只能展现一行文字~,我的学习就是通过这个最简单的适配器开始 正文: 完成这个ArrayAdapter需要三步:1.初始化数据 ...

  7. Python基础笔记:input()输入与数据类型转换

    input就是个万能输入,不过input输入的元素都是以str形式保存的,如果要他作为一个整数的话,就需要进行数据类型转换. input的使用 name=input('please input you ...

  8. 百度easydl之图像分类构建是否佩戴口罩模型

    2020-02-14 今天试了下百度esaydl的图像分类方面的功能,其优点是主需要上传自己的数据集,不需要关注模型训练,就可以得到相应的结果.最后得到的模型可以调用云api在本地进行运行. 网址:h ...

  9. oracle11g导出dmp文件时不能导出空表,导致缺表

    一.执行 select 'analyze table '||table_name||' compute statistics;' from user_tables; 将该查询语句查询到的结果粘贴到sq ...

  10. C#编码习惯2

    1.一定要用大括号括住流程控制元素,如for,while,if,switch内嵌的代码,即便只包含一行代码. 2.如果语句中有else if,一定要有一个else跟着最后一个else if. 3.只要 ...