前言

with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,

比如文件使用后自动关闭/线程中锁的自动获取和释放等。

问题引出

如下代码:

file = open("1.txt")
data = file.read()
file.close()

上面代码存在2个问题: 
(1)文件读取发生异常,但没有进行任何处理; 
(2)可能忘记关闭文件句柄;

改进

try:
f = open('xxx')
except:
print('fail to open')
exit(-1)
try:
do something
except:
do something
finally:
f.close()

虽然这段代码运行良好,但比较冗长。 
而使用with的话,能够减少冗长,还能自动处理上下文环境产生的异常。如下面代码:

with open("1.txt") as file:
data = file.read()

with 工作原理

(1)紧跟with后面的语句被求值后,返回对象的“–enter–()”方法被调用,这个方法的返回值将被赋值给as后面的变量; 
(2)当with后面的代码块全部被执行完之后,将调用前面返回对象的“–exit–()”方法。 
with工作原理代码示例:

class Sample:
def __enter__(self):
print "in __enter__"
return "Foo"
def __exit__(self, exc_type, exc_val, exc_tb):
print "in __exit__"
def get_sample():
return Sample()
with get_sample() as sample:
print "Sample: ", sample

代码的运行结果如下:

in __enter__
Sample: Foo
in __exit__

可以看到,整个运行过程如下: 
(1)enter()方法被执行; 
(2)enter()方法的返回值,在这个例子中是”Foo”,赋值给变量sample; 
(3)执行代码块,打印sample变量的值为”Foo”; 
(4)exit()方法被调用;

【注:】exit()方法中有3个参数, exc_type, exc_val, exc_tb,这些参数在异常处理中相当有用。 
exc_type: 错误的类型 
exc_val: 错误类型对应的值 
exc_tb: 代码中错误发生的位置 
示例代码:

class Sample():
def __enter__(self):
print('in enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print "type: ", exc_type
print "val: ", exc_val
print "tb: ", exc_tb
def do_something(self):
bar = 1 / 0
return bar + 10
with Sample() as sample:
sample.do_something()

程序输出结果:

in enter
Traceback (most recent call last):
type: <type 'exceptions.ZeroDivisionError'>
val: integer division or modulo by zero
File "/home/user/cltdevelop/Code/TF_Practice_2017_06_06/with_test.py", line 36, in <module>
tb: <traceback object at 0x7f9e13fc6050>
sample.do_something()
File "/home/user/cltdevelop/Code/TF_Practice_2017_06_06/with_test.py", line 32, in do_something
bar = 1 / 0
ZeroDivisionError: integer division or modulo by zero Process finished with exit code 1

总结

实际上,在with后面的代码块抛出异常时,exit()方法被执行。开发库时,清理资源,关闭文件等操作,都可以放在exit()方法中。 
总之,with-as表达式极大的简化了每次写finally的工作,这对代码的优雅性是有极大帮助的。 
如果有多项,可以这样写:

With open('1.txt') as f1, open('2.txt') as  f2:
do something

参考网址

http://blog.kissdata.com/2014/05/23/python-with.html

python 中 with 用法的更多相关文章

  1. python中xrange用法分析

    本文实例讲述了python中xrange用法.分享给大家供大家参考.具体如下: 先来看如下示例: >>> x=xrange(0,8) >>> print x xra ...

  2. python 中@ 的用法【转】

    这只是我的个人理解: 在Python的函数中偶尔会看到函数定义的上一行有@functionName的修饰,当解释器读到@的这样的修饰符之后,会先解析@后的内容,直接就把@下一行的函数或者类作为@后边的 ...

  3. Python中flatten用法

    Python中flatten用法 原创 2014年04月16日 10:20:02 标签: Python / flatten 22667 一.用在数组 >>> a = [[1,3],[ ...

  4. 列表[‘hello’ , ‘python’ ,’!’ ] 用多种方法拼接,并输出’hello python !’ 以及join()在python中的用法简介

    列表[‘hello’ , ‘python’ ,’!’ ] 用多种方法拼接,并输出’hello python !’ 使用字符串链接的四种方法都可以创建 字符串拼接一共有四种方法,也可以应用到列表的拼接中 ...

  5. python中“end=”用法

    python中“end=”用法:例如print(“#”,end=" \n"),默认换行,print(“#”,end=" ")则在循环中不换行

  6. python中pkl用法

    原文连接:https://www.jianshu.com/p/2ecadebe6d13 python中pkl用法 经常遇到在Python程序运行得到了一些字符串.列表.字典等数据,想要长久的保存下来, ...

  7. Python中print用法里面% ,"%s 和 % d" 代表的意思

    Python 编程 里面% . "%s 和 % d" 代表的意思 %s,表示格化式一个对象为字符 %d,整数 "Hello, %s"%"zhang3& ...

  8. 详解python中@的用法

    python中@的用法 @是一个装饰器,针对函数,起调用传参的作用. 有修饰和被修饰的区别,‘@function'作为一个装饰器,用来修饰紧跟着的函数(可以是另一个装饰器,也可以是函数定义). 代码1 ...

  9. python中*的用法

    在python中,很多情况下会用到*,下面举一些例子来说明*的用法 1.数字计算中,*代表乘法,**代表求幂 print('2乘以3值为:%s'%(2*3)) print('2的3次方值为:%s'%( ...

  10. python中print用法

    print用法 参考文档:https://blog.csdn.net/sinat_28576553/article/details/81154912 目录 一.print()函数概述 二.变量的输出 ...

随机推荐

  1. http://www.cnblogs.com/snake-hand/p/3206655.html

    1 public class MainActivity extends Activity { 2 3 private ListView listView; 4 private ArrayList< ...

  2. 容器学习(一):动手模拟spring的IoC

    介绍 学习经典框架的实现原理以及设计模式在事实上际中的运用,是很有必要的,能够让我们更好进行面向对象. 本篇文章就来模拟Spring的IOC功能.明确原理后,能够更好的使用它,进而为进行面向对象提供一 ...

  3. eclipse全屏模式

  4. windows、linux mysql部署

    阅读目录: 1.Windows下安装MySQL 2.Linux下安装MySQL 序章: MySQL是个小型的数据库,用来自己做小项目,做学习练习什么的再适合不过了,不过新手总会被一些莫名奇妙的问题难住 ...

  5. Docker 安装使用

    1:安装 在Linux上安装Docker,要求64位操作系统,并且内核版本需求为3.10以上,查看本机Linux内核版本: [root@localhost ~]# uname -r -.el7.x86 ...

  6. Apache+Tomcat负载均衡集群搭建

    1.所需软件 apache_2.2.4-win32-x86-no_ssl.apacheserver mod_jk-apache-2.2.4连接器,连接apache和tomcat apache-tomc ...

  7. vue 笔记二

    vue制作weibo 交互 vue-> 1.0 vue-resource ajax php 服务器环境(node) this.$http.get()/post()/jsonp() this.$h ...

  8. vue 源码 断点调试

    1.添加sourceMap sourceMap: true 2.npm run dev 会生成vue.js.map 3.断点调试 <!DOCTYPE html> <html> ...

  9. 解决-bash: fork: retry: Resource temporarily unavailable (修改最大线程数)

    错误提示的本质是Linux操作系统无法创建更多进程,导致出错.因此要解决这个问题需要修改Linux允许创建更多的进程. 方案一: cat /etc/security/limits.conf echo ...

  10. 在Html.ActionLink中运用二维判断语句

    @Html.ActionLink("公告信息", "notice", "article", null, new { @class = Vie ...