python的with语句,超级强大
With语句是什么?
有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。
如果不用with语句,代码如下:
|
1
2
3
|
file = open("/tmp/foo.txt")data = file.read()file.close() |
这里有两个问题。一是可能忘记关闭文件句柄;二是文件读取数据发生异常,没有进行任何处理。下面是处理异常的加强版本:
|
1
2
3
4
5
|
file = open("/tmp/foo.txt")try: data = file.read()finally: file.close() |
虽然这段代码运行良好,但是太冗长了。这时候就是with一展身手的时候了。除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常。下面是with版本的代码:
|
1
2
|
with open("/tmp/foo.txt")file: data = file.read() |
with如何工作?
这看起来充满魔法,但不仅仅是魔法,Python对with的处理还很聪明。基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。
紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。
下面例子可以具体说明with如何工作:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#!/usr/bin/env#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 print "sample:", |
运行代码,输出如下
|
1
2
3
4
|
bash-3.2$/with_example01.pyInsample:In |
正如你看到的,
1. __enter__()方法被执行
2. __enter__()方法返回的值 - 这个例子中是"Foo",赋值给变量'sample'
3. 执行代码块,打印变量"sample"的值为 "Foo"
4. __exit__()方法被调用
with真正强大之处是它可以处理异常。可能你已经注意到Sample类的__exit__方法有三个参数- val, type 和 trace。 这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#!/usr/bin/env#class Sample: def __enter__(self): return self def __exit__(self, type, print "type:", type print "value:", print "trace:", def do_something(self): bar = 1/0 return bar + 10with sample.do_something() |
这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有__enter__()和__exit__()方法即可。此例中,Sample()的__enter__()方法返回新创建的Sample对象,并赋值给变量sample。
代码执行后:
|
1
2
3
4
5
6
7
8
9
10
|
bash-3.2$/with_example02.pytype:type 'exceptions.ZeroDivisionError'>value:or modulotrace:object at 0x1004a8128>Traceback File "./with_example02.py",19, in <module> sample.do_something() File "./with_example02.py",15, in do_something bar = 1/0ZeroDivisionError:or modulo |
实际上,在with后面的代码块抛出任何异常时,__exit__()方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给__exit__()方法,因此抛出的ZeroDivisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在__exit__方法当中。
因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。
示例代码可以在Github上面找到。
python的with语句,超级强大的更多相关文章
- 理解python的with语句
Python’s with statement provides a very convenient way of dealing with the situation where you have ...
- 转: 理解Python的With语句
Python’s with statement provides a very convenient way of dealing with the situation where you have ...
- python——异常except语句用法与引发异常
except: #捕获所有异常 except: <异常名>: #捕获指定异常 except:<异常名1,异常名2):捕获异常1或者异常2 except:<异常名>,< ...
- Python之with语句
Python之with语句 在Python中,我们在打开文件的时候,为了代码的健壮性,通常要考虑一些异常情况,比如: try: ccfile = open('/path/data') content ...
- (Python )控制流语句if、for、while
这一节,我们将学习Python的控制流语句,主要包括if.for.while.break.continue 和pass语句 1. If语句 if语句也许是我们最熟悉的语句.其使用方法如下: x=inp ...
- Python的with语句
写过多线程程序的人肯定对各种锁很熟悉,尤其是下面这种代码 def lock_usage: lock.Lock() if(...) : lock.Unlock() return lock.Unlock( ...
- Python学习教程(learning Python)--3.3.4 Python的if-elif-else语句
Python的if-elif-else语句用于多种条件判断后选择某个语句块执行.该语句可以利用一系列条件表达式进行检查,并在某个表达式为真的情况下执行相应的代码.需要注意的是,虽然if/elif/el ...
- 简单探讨python中的语句和语法
python程序结构 python"一切皆对象",这是接触python听到最多的总结了.在python中最基层的单位应该就是对象了,对象需要靠表达式建立处理,而表达式往往存在于语句 ...
- python assert 断言语句的作用
python assert 断言语句的作用 assert语句的应用场景 使用assert语句是一个很好的习惯. 我们在编写代码的时候, 不知道程序会在什么时候崩溃, 与其让它在深度运行时崩溃, 不如预 ...
随机推荐
- UU农场平台开发 UU农场拆复利系统
UU农场平台开发 UU农场拆复利系统今年比较新的一款游戏,类似于QQ农场,但又加入了很多新型的互联网理财模式!UU农场平台开发 UU农场拆复利系统.UU农场开发.UU农场游戏平台开发.UU农场平台开发 ...
- jQuery DataTable 删除数据后重新加载
问题描述: 利用jQuery Datatable和artTemplate组合来做的表格.但是当删除数据时,需要重新加载table里的数据.但是问题是datatable并没有直接的重新渲染,反而给数据累 ...
- 从C#到TypeScript - Reflect
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- 每天一个linux命令(43)--netstat命令
netstat 命令用于显示与 IP TCP UDP 和 ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况.netstat 是在内核中访问网络及相关信息的程序,它能提供TCP连接,T ...
- 微信公众平台开发-access_token获取及应用(含源码)
微信公众平台开发-access_token获取及应用(含源码)作者: 孟祥磊-<微信公众平台开发实例教程> 很多系统中都有access_token参数,对于微信公众平台的access_to ...
- C语言中NULL的定义
用C语言编程不能不说指针,说道指针又不能不提NULL,那么NULL究竟是个什么东西呢? C语言中又定义,定义如下: #undef NULL #if defined(__cplusplus) #defi ...
- Prerender.io - 预渲染架构,提高AngularJS SEO
近些年来,越来越多的JavaScript框架(即AngularJS,BackboneJS,ReactJS)变得越来越流行.许多公司和开发人员使用这些JavaScript框架开发应用程序.这些框架有很多 ...
- Java代码块详解
Java中代码块指的是用 {} 包围的代码集合,分为4种:普通代码块,静态代码块,同步代码块,构造代码块 普通代码块: 定义:在方法.循环.判断等语句中出现的代码块 修饰:只能用标签修饰 位置:普通代 ...
- PetaPoco 快速上手
今天来给大家分享一个好用的轻型的.net框架的ORM——PetaPoco 本着快速上手的原则,我们通过和EF对比,让大家能快速使用PetaPoco PetaPoco大家可能没有听说过,但大家一定听说过 ...
- (六)javascriptJS中定义对象的几种方式(转)
JavaScript学习12 JS中定义对象的几种方式 转自: http://www.cnblogs.com/mengdd/p/3697255.html JavaScript中没有类的概念,只有对象 ...