Usage of python with as

What is the With statement?
There are some tasks that may need to be set up beforehand and cleaned up afterwards. For this scenario, Python's with statement provides a very convenient way to handle it. A good example is file handling, you need to get a file handle, read data from the file, and then close the file handle.
If the with statement is not used, the code is as follows:
file = open("/tmp/foo.txt")
data = file.read()
file.close()
There are two problems here. One is that you may forget to close the file handle; the other is that the file read data is abnormal and no processing is performed. Here's an enhanced version that handles exceptions:
file = open("/tmp/foo.txt")
try:
    data = file.read()
finally:
    file.close()
While this code works fine, it is too verbose. Now is the time to have a go. In addition to having a more elegant syntax, with can also handle exceptions generated by the context. Here is the code for the with version:
with open("/tmp/foo.txt") as file:
    data = file.read()

 

How does with work?

It looks like magic, but it's not just magic, Python's handling of with is clever. The basic idea is that the object evaluated by with must have an __enter__() method and an __exit__() method.

After the statement following with is evaluated, the __enter__() method of the returned object is called, and the return value of this method will be assigned to the variable following as. When the code blocks following with are all executed, the __exit__() method of the previously returned object will be called.

The following example illustrates how with works:
copy code
#!/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
copy code
Run the code, the output is as follows
In __enter__()
sample: Foo
In __exit__()
As you can see,
1. The __enter__() method is executed
2. The value returned by the __enter__() method - "Foo" in this example, assigned to the variable 'sample'
3. Execute the code block and print the value of the variable "sample" as "Foo"
4. The __exit__() method is called
The real power of with is that it can handle exceptions. You may have noticed that the __exit__ method of the Sample class has three parameters - val, type and trace. These parameters are quite useful in exception handling. Let's change the code to see how it works.
copy code
#!/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()
copy code
In this example, get_sample() after with becomes Sample(). It doesn't matter, as long as the object returned by the statement following with has __enter__() and __exit__() methods. In this example, the __enter__() method of Sample() returns the newly created Sample object and assigns it to the variable sample.
After the code is executed:
copy code
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
copy code
In fact, the __exit__() method is executed when any exception is thrown by the code block following with. As the example shows, when the exception is thrown, the associated type, value and stack trace are passed to the __exit__() method, so the thrown ZeroDivisionError exception is printed. When developing a library, operations such as cleaning up resources, closing files, etc., can be placed in the __exit__ method.
Therefore, Python's with statement is an effective mechanism to make the code more concise, and at the same time, when an exception occurs, the cleanup work is easier.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324845763&siteId=291194637
Recommended