python的with用法
With语句是什么?
有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。
如果不用with语句,代码如下:
file = open("/tmp/foo.txt")
data = file.read()
file.close()
这里有两个问题:
- 一是可能忘记关闭文件句柄;
- 二是文件读取数据发生异常,没有进行任何处理。
下面是处理异常的加强版本:
try:
f = open('xxx')
except:
print 'fail to open'
exit(-1)
try:
do something
except:
do something
finally:
f.close()
虽然这段代码运行良好,但是太冗长了。
这时候就是with一展身手的时候了。除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常。
下面是with版本的代码:
with open("/tmp/foo.txt") as file:
data = file.read()
with如何工作?
- 紧跟with后面的语句被求值后,返回对象的 __enter__() 方法被调用,这个方法的返回值将被赋值给as后面的变量。
- 当with后面的代码块全部被执行完之后,将调用前面返回对象的 __exit__()方法。
下面例子可以具体说明with如何工作:
#!/usr/bin/env python
# with_example01.py
class Sample:
def __enter__(self):
print "In __enter__()"
return "Foo"
def __exit__(self, type, value, trace):
print "In __exit__()"
def get_sample():
return Sample()
with get_sample() as sample:
print "sample:", sample
运行代码,输出如下
bash-3.2$ ./with_example01.py
In __enter__()
sample: Foo
In __exit__()
正如你看到的: 1. __enter__()方法被执行 2. __enter__()方法返回的值 - 这个例子中是”Foo”,赋值给变量’sample’ 3. 执行代码块,打印变量”sample”的值为 “Foo” 4. __exit__()方法被调用 with真正强大之处是它可以处理异常。
可能你已经注意到Sample类的 __exit__ 方法有三个参数 val, type 和 trace。 这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。
#!/usr/bin/env python
# with_example02.py
class Sample:
def __enter__(self):
return self
def __exit__(self, type, value, trace):
print "type:", type
print "value:", value
print "trace:", trace
def do_something(self):
bar = 1/0
return bar + 10
with Sample() as sample:
sample.do_something()
这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有 __enter__() 和 __exit__() 方法即可。此例中,Sample()的 __enter__() 方法返回新创建的Sample对象,并赋值给变量sample。
代码执行后:
bash-3.2$ ./with_example02.py
type: <type 'exceptions.ZeroDivisionError'>
value: integer division or modulo by zero
trace: <traceback object at 0x1004a8128>
Traceback (most recent call last):
File "./with_example02.py", line 19, in <module>
sample.do_something()
File "./with_example02.py", line 15, in do_something
bar = 1/0
ZeroDivisionError: integer division or modulo by zero
实际上,在with后面的代码块抛出任何异常时,__exit__() 方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给 __exit__() 方法,因此抛出的ZeroDivisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在 __exit__ 方法当中。
另外,__exit__ 除了用于tear things down,还可以进行异常的监控和处理,注意后几个参数。要跳过一个异常,只需要返回该函数True即可。
下面的样例代码跳过了所有的TypeError,而让其他异常正常抛出。
def __exit__(self, type, value, traceback):
return isinstance(value, TypeError)
上文说了 __exit__ 函数可以进行部分异常的处理,如果我们不在这个函数中处理异常,他会正常抛出,这时候我们可以这样写(python 2.7及以上版本,之前的版本参考使用contextlib.nested这个库函数):
try:
with open( "a.txt" ) as f :
do something
except xxxError:
do something about exception
总之,with-as表达式极大的简化了每次写finally的工作,这对保持代码的优雅性是有极大帮助的。
如果有多个项,我们可以这么写:
with open("x.txt") as f1, open('xxx.txt') as f2:
do something with f1,f2
因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。
python的with用法的更多相关文章
- Python回调函数用法实例详解
本文实例讲述了Python回调函数用法.分享给大家供大家参考.具体分析如下: 一.百度百科上对回调函数的解释: 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函 ...
- day01-day04总结- Python 数据类型及其用法
Python 数据类型及其用法: 本文总结一下Python中用到的各种数据类型,以及如何使用可以使得我们的代码变得简洁. 基本结构 我们首先要看的是几乎任何语言都具有的数据类型,包括字符串.整型.浮点 ...
- 【Python】关于Python有意思的用法
开一篇文章,记录关于Python有意思的用法,不断更新 1.Python树的遍历 def sum(t): tmp=0 for k in t: if not isinstance(k,list): tm ...
- python中xrange用法分析
本文实例讲述了python中xrange用法.分享给大家供大家参考.具体如下: 先来看如下示例: >>> x=xrange(0,8) >>> print x xra ...
- 浅谈Python在信息学竞赛中的运用及Python的基本用法
浅谈Python在信息学竞赛中的运用及Python的基本用法 前言 众所周知,Python是一种非常实用的语言.但是由于其运算时的低效和解释型编译,在信息学竞赛中并不用于完成算法程序.但正如LRJ在& ...
- python scapy的用法之ARP主机扫描和ARP欺骗
python scapy的用法之ARP主机扫描和ARP欺骗 目录: 1.scapy介绍 2.安装scapy 3.scapy常用 4.ARP主机扫描 5.ARP欺骗 一.scapy介绍 scapy是一个 ...
- python函数的用法
python函数的用法 目录: 1.定义.使用函数 1.函数定义:def 2.函数调用:例:myprint() 3.函数可以当作一个值赋值给一个变量 例:a=myprint() a() 4.写r ...
- python 中@ 的用法【转】
这只是我的个人理解: 在Python的函数中偶尔会看到函数定义的上一行有@functionName的修饰,当解释器读到@的这样的修饰符之后,会先解析@后的内容,直接就把@下一行的函数或者类作为@后边的 ...
- Python Enum 枚举 用法汇总
Python Enum 枚举 用法汇总 import os import sys if sys.version_info.major + sys.version_info.minor * 0.1 &l ...
- python查看对象用法
python查看类用法: dir(object_name)
随机推荐
- 11_MySQL_分页查询
# 分页查询/* 应用场景:要显示的数据,一页显示不全,需要分页提交sql请求 语法: select 查询列表 from 表 [join type]表2 on 连接条件 where 筛选条件 grou ...
- Learn Rails5.2 Bundler ; Forms
如果一个Rubyer想要提供一个功能或某个程序或程序的集合给其他Rubyer使用,这个Rubyer可以创建一个package,这个package就叫做gems. 可以通过gem install安装. ...
- System.ComponentModel.DataAnnotations 命名空间和RequiredAttribute 类
System.ComponentModel.DataAnnotations 命名空间提供定义 ASP.NET MVC 和 ASP.NET 数据控件的类的特性. RequiredAttribute 指定 ...
- snmpwalk-MIB of S5700-idc-stack
IF-MIB:.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescrOID:.1.3.6.1.2.1.2.2.1.2 针 ...
- [Python开发工具] Pycharm之快捷键
[Python开发工具] Pycharm之快捷键 1 全局搜索: Ctrl+Shift+F,不过PyCharm的更强大, 你可以点选左侧某个目录后再按Ctrl+Shift+F, 这样默认会搜索改目录; ...
- SSH-Auditor:一款SSH弱密码探测工具
SSH-Auditor:一款SSH弱密码探测工具 freebuf 2018-09-16 ssh-auditor是一款可帮助你探测所在网络中ssh弱密码的工具. 特性 以下操作ssh-auditor都 ...
- angularJs---route
route route---‘路由’ ajax的弊端: 1.ajax请求不会留下history记录 2.用户无法直接通过url进入应用中的指定页面(保存书签,分享朋友?) 3.ajax不利于SEO 前 ...
- Jquery倒计时源码分享
在静态页添加显示倒计时的容器,并引用下面脚本,代入时间参数即可使用. timeoutDate——到期时间,时间格式为2014/01/01或2014/1/1 D——天 H——小时 M——分钟 S——秒 ...
- docker部署mysql
1. 下载 [root@localhost my.Shells]# ./dockerStart.sh start or stop start Redirecting to /bin/systemctl ...
- Win7系统Visual Studio 2013配置OpenCV3.1图文详解
Win7系统Visual Studio 2013配置OpenCV3.1图文详解 OpenCV3.1对硬件加速和移动开发的支持相对于老版本都有了较大改进,支持新的开发工具,更易于扩展,配置方式也比以前简 ...