the python with usage (reprint)

Original Address: https: //www.cnblogs.com/wanglei-xiaoshitou1/p/9238275.html

 

First, what with statement is?

There are some tasks, you may need to set in advance, and afterwards do the cleanup work. For this scenario, Python with statement provides a very convenient approach. A good example is the file handle, you need to obtain a file handle to read data from the file, and then close the file handle.

If not with the statement, as follows:

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

There are two issues:

One may forget to close the file handle; 
the second is the occurrence of abnormal data file read, without any treatment.

Here is the deal with abnormal enhanced version:

try:
    f = open('xxx') except: print 'fail to open' exit(-1) try: do something except: do something finally: f.close()

Although this code works well, but it is too cumbersome.

This time is a go with the time. In addition to a more elegant syntax, with also a good handle exceptions context of the environment.

The following is a version of the code with:

with open("/tmp/foo.txt") as file: data = file.read()
-----------------------------------------------------------------------------------------------------------------------------
二、
How to work with?

After keeping up with the latter statement is evaluated, the returned object __enter __ () method is called, the return value of this method will be assigned to the latter as variables. 
After the block with all the latter is completely executed, returns the call to the front object The __exit __ () method.

The following example can specify with how it works:

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

 

Run the code, the following output

bash-3.2$ ./with_example01.py
In __enter__() sample: Foo In __exit__()
As you can see: 1. __enter __ () method is executed 2. __enter __ () method returns the value - in this example is the "Foo", assigned to the variable 'sample' 3. code block is executed, the print variable "sample" of value "Foo" 4. __exit __ () method is called  
with real power is that it can handle the exception. You may have noticed __exit__ method Sample class has three parameters val, type and trace. These parameters are very useful in the exception process. Let's change the code to see how specific work.
! # / usr / bin / env Python
# with_example02.py class the Sample:
DEF __enter__ (Self):
return Self
DEF __exit__ (Self, of the type, value, the trace):
Print "of the type:", of the type
Print "value:", value
Print "the trace:", the trace
DEF do_something (Self):
bar = . 1/ 0
return bar + 10
with the Sample ()as sample:
sample.do_something()

In this case, with the latter get_sample () become Sample (). This has nothing to do, just keep up with the object behind the statement returned there __enter __ () and __exit __ () method can be. In this example, Sample () of __enter __ () method returns the Sample newly created object, and assigned to the variable sample.

Code execution:

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


In fact, when the back of the block with no exception is thrown, __ __ Exit () method is executed. As shown in the example, when an exception is thrown, the associated type, value and pass stack trace The __exit __ () method, therefore thrown exception ZeroDivisionError is printed out. When developing libraries, cleaning up resources, close the file, etc. operations, which can be placed __exit__ method.

In addition, __ exit__ addition to tear things down, an abnormality can be monitored and processed, pay attention to several parameters. To skip an exception, just return to the True function.

The following sample code to skip all the TypeError, and let the other exceptions normally thrown.

def __exit__(self, type, value, traceback): return isinstance(value, TypeError)

In short, with-as an expression greatly simplifies each write finally work, which is to maintain elegance of the code is of great help.

If there are multiple items, we can write:

with open("x.txt") as f1, open('xxx.txt') as f2: do something with f1,f2

 

Therefore, Python's with statement is to provide an effective mechanism to make the code more concise, but when an abnormality occurs, clean-up easier.

Third, related terms

要使用 with 语句,首先要明白上下文管理器这一概念。有了上下文管理器,with 语句才能工作。 
下面是一组与上下文管理器和with 语句有关的概念。 
上下文管理协议(Context Management Protocol):包含方法 __enter__() 和 __exit__(),支持该协议的对象要实现这两个方法。 
上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了__enter__() 和 __exit__() 方法。上下文管理器定义执行 with 语句时要建立的运行时上下文,负责执行 with 语句块上下文中的进入与退出操作。通常使用 with 语句调用上下文管理器,也可以通过直接调用其方法来使用。 
运行时上下文(runtime context):由上下文管理器创建,通过上下文管理器的 __enter__() 和__exit__() 方法实现,__enter__() 方法在语句体执行之前进入运行时上下文,__exit__() 在语句体执行完后从运行时上下文退出。with 语句支持运行时上下文这一概念。 
上下文表达式(Context Expression):with 语句中跟在关键字 with 之后的表达式,该表达式要返回一个上下文管理器对象。 
语句体(with-body):with 语句包裹起来的代码块,在执行语句体之前会调用上下文管理器的 __enter__() 方法,执行完语句体之后会执行__exit__() 方法。

Guess you like

Origin www.cnblogs.com/qyit/p/11646807.html