`

with语句

 
阅读更多

转自http://sdqali.in/blog/2012/07/09/understanding-pythons-with/

Understanding Python's "with" statement

09 July 2012

What is it?

Python’s with statement provides a very convenient way of dealing with the situation where you have to do a setup and teardown to make something happen. A very good example for this is the situation where you want to gain a handler to a file, read data from the file and the close the file handler.

Without the with statement, one would write something along the lines of:

 

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

 

There are two annoying things here. First, you end up forgetting to close the file handler. The second is how to handle exceptions that may occur once the file handler has been obtained. One could write something like this to get around this:

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

 

While this works well, it is unnecessarily verbose. This is where with is useful. The good thing about with apart from the better syntax is that it is very good handling exceptions. The above code would look like this, when using with:

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

How does it work?

While this might look like magic, the way Python handles with is more clever than magic. The basic idea is that the statement after with has to evaluate an object that responds to an __enter__() as well as an __exit__() function.

After the statement that follows with is evaluated, the __enter__() function on the resulting object is called. The value returned by this function is assigned to the variable following as. After every statement in the block is evaluated, the __exit__() function is called.

This can be demonstrated with the following example:

#!/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

 When executed, this will result in:

bash-3.2$ ./with_example01.py
In __enter__()
sample: Foo
In __exit__()

As you can see,

  1. The __enter__() function is executed
  2. The value returned by it – in this case "Foo" is assigned to sample
  3. The body of the block is executed, thereby printing the value of sample ie. "Foo"
  4. The __exit__() function is called.

What makes with really powerful is the fact that it can handle exceptions. You would have noticed that the __exit__() function for Sample takes three arguments – val, type and trace. These are useful in exception handling. Let’s see how this works by modifying the above example.

#!/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()

Notice how in this example, instead of get_sample(), with takes Sample(). It does not matter, as long as the statement that follows with evaluates to an object that has an __enter__() and __exit__() functions. In this case, Sample()’s __enter__() returns the newly created instance of Sample and that is what gets passed to sample.

When executed:

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

Essentially, if there are exceptions being thrown from anywhere inside the block, the __exit__() function for the object is called. As you can see, the type, value and the stack trace associated with the exception thrown is passed to this function. In this case, you can see that there was a ZeroDivisionError exception being thrown. People implementing libraries can write code that clean up resources, close files etc. in their __exit__() functions.

Thus, Python’s with is a nifty construct that makes code a little less verbose and makes cleaning up during exceptions a bit easier.

I have put the code examples given here on Github.

Tagged under code, python

分享到:
评论

相关推荐

    DB2公共表表达式(WITH语句使用).pdf

    【DB2公共表表达式(WITH语句使用)】 公共表表达式(Common Table Expression,简称CTE)在DB2数据库系统中是一个非常强大的工具,主要用于定义临时的、只在查询过程中存在的表。WITH语句使得复杂的查询变得更加...

    javascript完美学习视频教程-----11.javascript流程控制-跳转语句、with语句

    本教程专注于JavaScript的流程控制,特别是跳转语句和with语句,这两部分是编写高效、逻辑清晰的JavaScript代码的关键。 首先,我们来详细讲解一下跳转语句。在编程中,跳转语句用于改变程序执行的顺序,使得代码...

    Javascript中With语句用法实例

    With语句在JavaScript中是一种特殊的语法结构,它的作用是扩展一个语句的作用域链。通过with语句可以不需要重复引用某个对象就能多次访问该对象的属性。这在某些情况下可以减少代码的书写量,但同时它也存在争议,...

    05-python-迭代器-生成器-with语句和上下文管理器-修饰符

    在Python编程语言中,迭代器、生成器、with语句和上下文管理器以及修饰符是四个非常重要的概念,它们在处理数据流和资源管理时起着关键作用。以下是关于这些知识点的详细解释: 1. **迭代器**: - 迭代器是一种...

    VB With语句块实例

    在Visual Basic (VB)编程语言中,`With`语句块是一种非常实用的语法结构,它允许程序员在一段代码中多次引用同一个对象,而无需反复输入对象名。这极大地提高了代码的可读性和效率,尤其是在处理复杂对象或者需要对...

    Python with语句和过程抽取思想

    python中的with语句使用于对资源进行访问的场合,保证不管处理过程中是否发生错误或者异常都会执行规定的__exit__(“清理”)操作,释放被访问的资源,比如有文件读写后自动关闭、线程中锁的自动获取和释放等。...

    Vue js with语句原理及用法解析

    // 使用with语句 with (obj) { var a = a; var b = b; var c = c; } ``` 使用`with`可以让代码更简洁,因为不需要反复写`obj.`。然而,这也有其潜在的问题: 1. **性能影响**:JavaScript引擎为了优化代码,...

    152-4 使用With语句引用对象.xlsm

    152-4 使用With语句引用对象.xlsm

    python with语句的原理与用法详解

    本文实例讲述了python with语句的原理与用法。分享给大家供大家参考,具体如下: 之前看到一篇博客说博主python面试时遇到面试官提问with的原理,而那位博主的博文没有提及with原理,故有此文。 关于with语句,官方...

    关于python的with语句使用with-as语句也有的人称为context manager

    Python的`with`语句是一种强大的工具,它简化了资源管理,特别是在处理文件、网络连接、锁等需要在使用后释放的资源时。`with`语句也被称为上下文管理器(Context Manager),因为它遵循了Python的上下文管理协议。 ...

    深入浅析JavaScript中with语句的理解

    JavaScript 有个 with 关键字, with 语句的原本用意是为逐级的对象访问提供命名空间式的速写方式。这篇文章主要介绍了JavaScript中with语句的相关知识,感兴趣的朋友一起学习吧

    python中with语句结合上下文管理器操作详解

    我们可以通过with语句结合上下文管理器简化一些操作。 使用with语句结合自定义上下文管理器完成数据库相应的操作,代码实现如下: # 1. 导入模块 import pymysql # 创建自定义上下文管理器对象 class MyDatabase...

    Python中的with语句与上下文管理器学习总结

    ### Python中的with语句与上下文管理器学习总结 #### 一、上下文管理器概述 **上下文管理器**是一种特殊类型的对象,它能够通过`__enter__()`和`__exit__()`这两个方法来控制资源的获取和释放。这种模式在Python中...

    js的with语句使用方法

    js的with语句使用方法 js的with语句是一种特殊的语句,用于简化对某个对象的多次访问。它可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性。要给对象创建新的属性,必须明确地引用该对象。...

    JavaScript严格模式禁用With语句的原因

    其中,严格模式对许多传统的不安全或容易引起混淆的特性进行了限制,其中之一就是禁用了“with语句”。 了解严格模式对with语句的限制之前,首先需要明白with语句的作用和它可能带来的问题。with语句主要用于将一段...

    Python 的 with 语句详解

    一、简介 with是从Python 2.5 引入的一个新的语法,更准确的说,是一种上下文的管理协议,用于...复制代码 代码如下:with EXPR as VAR: BLOCK根据PEP 343的解释,with…as…会被翻译成以下语句:复制代码 代码如下:mg

    Python中的With语句的使用及原理

    在Python编程语言中,`with`语句是一个强大的工具,用于简化资源的获取和释放,尤其是在处理文件、网络连接或需要进行清理操作的其他资源时。`with`语句通过确保资源在使用后总是被正确地关闭或释放,极大地提高了...

    with语句还能这么用,你会吗?——with语句和上下文管理器

    with语句和上下文管理器`启程“下面进行with语句的剖析,在自定义对象中支持with“进阶“加深理解“探索` 启程    with 语句究竟有哪些好处?它有助于简化一些通用资源管理模式,抽象出其中的功能,将其分解并重用...

    Python中的上下文管理器和with语句的使用

    上下文管理器的主要语法是 `with` 语句,通常与 `as` 关键字一起使用。例如,在文件操作中: ```python with open('file.py', 'w') as f: # 文件操作 f.write('# Hello Python') ``` 在这个例子中,`open('file....

Global site tag (gtag.js) - Google Analytics