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.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__()

正如你看到的,

__enter__()方法被执行

__enter__()方法返回的值 - 这个例子中是"Foo",赋值给变量'sample'

执行代码块,打印变量"sample"的值为 "Foo"

__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:

value: integer division or modulo by zero

trace:

Traceback (most recent call last):

File "./with_example02.py", line 19, in

sample.do_somet hing()

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__方法当中。

因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。

python中exit的作用_python __enter__ 与 __exit__的作用,以及与 with 语句的关系相关推荐

  1. python中delete怎么用_python删除np.deletePython基础教程05 - 缩进和选择

    缩进 Python最具特色的是用缩进来标明成块的代码.我下面以if选择结构来举例.if后面跟随条件,如果条件成立,则执行归属于if的一个代码块. 先看C语言的表达方式(注意,这是C,不是Python! ...

  2. python中if缩进规则_Python缩进与if语句 空格的魅力

    缩进 Python最具特色的是用缩进来标明成块的代码.我下面以if选择结构来举例.if后面跟随条件,如果条件成立,则执行归属于if的一个代码块. 先看C语言的表达方式(注意,这是C,不是Python! ...

  3. python中的缩进快捷键_python如何缩进

    以缩进来表示代码块,是python的特色,对养成好的编程习有非常大的帮助,那么python如何缩进呢?一起来了解下吧: python如何缩进 你需要记住的一样东西是错误的缩进会引发错误.例如: i = ...

  4. python中get函数作用_python get函数有什么作用?示例解析

    这篇文章之中我们来了解一下关于python字典之中的pythonget函数的相关知识,get函数是什么意思,他有什么作用都将会在接下来的文章之中得到解答. 描述 Python 字典(Dictionar ...

  5. python中pass的使用_Python中pass语句的作用

    Python中pass语句实际上一种不会产生任何操作的语句.主要用于创建空的代码块或空函数. 1.用于创建空的代码块 下面程序用于找出20以内所有能被3整除的整数. list1 = [] for i ...

  6. python中write什么意思_python file write () 方法概括及作用分析(实例)

    今天这篇文章我们来了解一下pythonwrite(),我会在这篇文章之中来讲解python中write方法以及pythonwrite属性而且还会将它能用在python编程之中的什么地方来进行说明.废话 ...

  7. super在python中是什么意思_python中super()的作用是什么

    python中super()的作用是什么 发布时间:2020-08-13 13:59:16 来源:亿速云 阅读:112 作者:小新 这篇文章主要介绍python中super()的作用是什么,文中介绍的 ...

  8. python中pass的含义_python中pass语句意义与作用(实例分析)

    想必大家都是刚刚才开始接触python这门语言的,今天这篇文章就来带大家来了解一下python这门语言之中常常会用到的一个语句pass语句.想必大家都很好奇python中pass作用是什么,接下来我就 ...

  9. python中time的函数_python中time库的time.time()函数的作用是什么

    python中time库的time.time()函数的作用是什么 python中time库的time.time()函数的作用是什么? 作用:Python time time() 返回当前时间的时间戳( ...

最新文章

  1. 智能手表音频特性测试_智能手表和传统手表怎么选?有这些需求选它更合适
  2. php怎么创建事务,php事务的实现方法介绍(代码示例)
  3. 无需编码创建app--应用之星制作app教程
  4. 以非泛型方式调用泛型方法(三)
  5. 通过 SAP UI5 的 TypeScript 开发环境,来学习什么是 DefinitelyTyped
  6. 有关VIM的一些笔记
  7. html5 动态 menuitem,利用HTML 5中的Menu和Menuitem元素快速创建菜单
  8. php中双等与三等,利用php中双等于和三等于的区别,无需密码拿到flag
  9. Mysql用户访问工作原理
  10. php反射API 获取属性/注释/方法 执行方法 实例
  11. redis介绍及常见用法
  12. ios 手势返回监听方法
  13. java sql 工具类_Java防SQL注入工具类
  14. 读后感系列-2.《看见》柴静(二)
  15. 强化学习-利用Q-Learning算法玩走方格游戏(C++)
  16. STC单片机不同数据类型串口打印输出示例程序
  17. STM32F4xx时钟配置的三种方法
  18. python换零钱_LeetCode-python 322.零钱兑换
  19. centos 设置新用户并设置使用sudo时,无需输入密码
  20. Android中的常见时区

热门文章

  1. SAP ABAP CI/CD持续集成,持续交付解决方案
  2. UI5 repository mapping and Component-preload.js UI5RepositoryPathMapping.xml
  3. how is my appointment opened in HCP
  4. Excel 2010 下拉菜单的制作方法
  5. 我回答的一个粉丝关于用编程语言模拟SAP事务的问题
  6. SAP CX Upscale Commerce : SAP全新推出的电商云平台
  7. 使用Kubernetes里的job计算圆周率后2000位
  8. java中multiply用法_java中BigDecimal加减乘除基本用法
  9. ipython安装_IPython 它不香吗?
  10. python 定义一个负数_其实Python不难学(4):Python如何处理文本数据