the python with

statement for the occasion with access to resources, ensuring that regardless of whether an exception occurs in the course of the implementation of the necessary "clean-up" operation, the release of resources.

For example, the file automatically shut down after use, thread lock automatically acquire and release.

with open('test.txt', 'r') as f:
    for line in f:
        print(line)

Operating mechanism

with VAR = EXPR:
    BLOCK

Equivalent to

VAR = EXPR 
VAR. __enter__ ()
 try : 
    BLOCK 
finally : 
    VAR. __exit__ ()

VAR corresponds to a context manager (context manager).

Context Manager

Class implements two methods The __enter __ () and The __exit __ () is a context manager.

class MyContextManager:
    def __enter__(self):
        print('before block run')
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('after block run')

Use context management MyContextManager

with MyContextManager():
    print('run block')

Output is as follows:

before block run
run block
after block run

MyContextManager can also accept parameters

class MyContextManager:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __enter__(self):
        print('before block run')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('after block run')

    def show(self):
        print('my name is:', self.name)
        print('my age is:', self.age)

Use context management MyContextManager again

with MyContextManager('logan', 27) as myCM:
    myCM.show()

Output is as follows:

before block run
my name is: logan
my age is: 27
after block run

Here used a as: with context_manager as target

The __enter context_manager the target corresponding to the return value __ () method returns the value may be context_manager itself, or may be other objects.

contextlib.contextmanager

 contextmanager to be decorated generator function, the result is a context manager.

import contextlib

@contextlib.contextmanager
def MyGenerator():
    print('before yield')
    yield
    print('after yield')

with MyGenerator():
    print('run block')

Output is as follows:

before yield
run block
after yield

Here yield nothing, a yield something to the following examples

import contextlib

@contextlib.contextmanager
def MyGenerator():
    print('before yield')
    yield 'context manager'
    print('after yield')

with MyGenerator() as cm:
    print('run block')
    print(cm)

Output is as follows:

before yield
run block
context manager
after yield

 

Note two points

1. The yield is similar to previous statements __enter __ (), similar to the statement following the yield The __exit __ () method.

2. yield return a context manager, if used as the statement, it will be assigned to as statement of target.

 

try...finally

When an exception within the try range, will immediately jump to the finally block. When finally block is finished, one exception is thrown up will continue.

 

References:

On the Python with statement

 

Reproduced in: https: //www.cnblogs.com/gattaca/p/7309192.html

Guess you like

Origin blog.csdn.net/weixin_34326179/article/details/93401900