Python with as 的用法
admin
2024-04-20 17:05:06
0

With语句是什么?
有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。
如果不用with语句,代码如下:

file = open("/tmp/foo.txt")
data = file.read()
file.close()

这里有两个问题。一是可能忘记关闭文件句柄;二是文件读取数据发生异常,没有进行任何处理。下面是处理异常的加强版本:

file = open("/tmp/foo.txt")
try:data = file.read()
finally:file.close()

虽然这段代码运行良好,但是太冗长了。这时候就是with一展身手的时候了。除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常。下面是with版本的代码:

with open("/tmp/foo.txt") as file:data = file.read()

with如何工作?

这看起来充满魔法,但不仅仅是魔法,Python对with的处理还很聪明。基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。

紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。

下面例子可以具体说明with如何工作:

#!/usr/bin/env python
# with_example01.pyclass 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

运行代码,输出如下

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.pyclass Sample:def __enter__(self):return selfdef __exit__(self, type, value, trace):print "type:", typeprint "value:", valueprint "trace:", tracedef do_something(self):bar = 1/0return bar + 10with Sample() as sample:sample.do_something()

这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有__enter__()和__exit__()方法即可。此例中,Sample()的__enter__()方法返回新创建的Sample对象,并赋值给变量sample。
代码执行后:

bash-3.2$ ./with_example02.py
type: 
value: integer division or modulo by zero
trace: 
Traceback (most recent call last):File "./with_example02.py", line 19, in sample.do_something()File "./with_example02.py", line 15, in do_somethingbar = 1/0
ZeroDivisionError: integer division or modulo by zero

实际上,在with后面的代码块抛出任何异常时,__exit__()方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给__exit__()方法,因此抛出的ZeroDivisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在__exit__方法当中。
因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。

相关内容

热门资讯

马斯克:SpaceX星舰下月将... IT之家 2 月 22 日消息,SpaceX 首席执行官埃隆 · 马斯克今天在 X 平台发消息称,星...
县城精品咖啡馆 , 靠春节“续... 县城咖啡馆 在县城卖30元一杯的咖啡,还是好生意吗? 见习作者 | 王汉星 编辑 | 魏佳 大年初二...
原创 白... 根据统计部门公布的数据,2025年1-12月份,甘肃全省GDP总值共计13697.5亿元,较上年同期...
带动旅游收入超24亿元,“世界... “世界超市”义乌,持续释放春晚磁力效应。 今年除夕夜,义乌分会场用短短八分钟,在总台2026年春晚征...
下周关注丨苹果公司举行年度股东... 【重磅新闻】 2月LPR将公布 2月24日,1年期和5年期以上LPR将公布最新值。中国人民银行授权全...
气疯了,特朗普宣布:把全球关税... 【文/观察者网 齐倩】 美国最高法院裁定关税非法后,美国总统特朗普越想越气,要把10%“”提高至1...
原创 续... 最近发现小区出现好多贴有新手上路的车贴,似乎有很多朋友完成了自己的汽车梦。那么什么是好车,适合你的就...
2026中国电影票房暂列全球第... “IT早报”时间,大家好,现在是 2026 年 2 月 22 日星期日,今天的重要科技资讯有: 早报...
特朗普将全球进口关税从10%上... 美国总统特朗普此前依据《贸易法》第122条,在其“对等关税”被最高法院裁定违法后,迅速启用一项新的全...
规律进行有氧运动 对改善大脑血... 大脑功能的维持高度依赖于持续且充足的血液供应。血液循环不仅输送氧气与营养物质,也负责清除代谢废物。当...
中国足协主席最新表态:足球要向... 据辽宁日报2月21日报道,春节假期,中国足协主席、辽宁省体育局原局长宋凯回到辽宁家中,几乎每天都守在...
陈云在上饶经开区调研企业生产 2月20日,农历正月初四,市委书记陈云在上饶经开区调研企业生产情况。他强调,要深入贯彻落实中央经济工...
原创 澳... 20万吨铁矿石从非洲起航,重重落地中国舟山港,这不是普通一船货,而是“掀桌子”的那一船。从非洲几内亚...
特朗普:税率将升至15%!数百... 据央视新闻,当地时间2月21日,美国总统特朗普在其社交平台“真实社交”上发文称,将把对全球商品加征1...
对冲基金经理罗伯・西特罗恩做空... 来源:环球市场播报 Discovery 资本的罗伯・西特罗恩表示:全球新兴市场存在大幅低估。 在 2...
多家银行密集出手,“盯上”孩子... 春节期间,儿童压岁钱的去向再次成为银行争夺业务的切入点。多家商业银行近段时间密集推出以“压岁钱”“儿...
微软游戏CEO菲尔·斯宾塞退休... 微软游戏CEO 菲尔·斯宾塞(Phil Spencer)将于 2 月 23 日退休, Xbox 总裁...
贺博生:黄金原油今日行情价格涨... 来源:市场资讯 黄金最新行情趋势分析: 2月19日,黄金消息面解析:周四亚洲时段,金价在4960美元...
比特币到底怎么买?这份攻略让你... >>点击获取下载地址<< 你是不是也动过买比特币的念头,却被各种术语和平台搞得晕头转向?别急,这篇指...