Data Science Club

Chinese data scientist community

Author: ChrisYZX, used Python artist/designer/economics

Blog: www.jianshu.com/u/45eabf52c…

The with statement is a compact version of the try/finally statement

In our daily use scenario, often operating some resources, such as the file object, database connection and a Socket connection, resources after the operation, regardless of the success of operation, the most important thing is to close the resources, resources open too much and not closed, complains, file operations, for example, usually we will write like this:

f = open('file.txt', 'w')
try:
    f.write("Hello")
finally:
    f.close()
Copy the code

But since the close method is required, there is no need to call it explicitly, so Python gives us a more elegant way to use the with statement:

with open('file.txt', 'w') as f:
    f.write("Hello")
Copy the code

After exiting the code block under the with statement, the f object will automatically execute its own close method to achieve a concise and elegant resource release.

Context manager principle

The f object automatically executes its own close method because it is a context manager, so let’s talk about what a context manager is.

Context managers are objects that internally implement __enter__ and __exit__ methods (such as the object obtained by the EXPR expression below)

It is commonly used as follows:

with EXPR as VAR:
    BLOCK
Copy the code

The execution of the above code is equivalent to:

ContextManager = EXPR
VAR = ContextManager.__enter__()
try:
    BLOCK
finally:
    ContextManager.__exit__()
Copy the code

An f object defines its own close method inside its __exit__ method, which automatically closes itself when a BLOCK is finished executing.

Custom context manager

To verify this, we define a file class that internally implements __enter__ and __exit__ methods:

class File: def __init__(self, filename, mode): self.filename = filename self.mode = mode def __enter__(self): Self. f def __exit__(self, exc_type=None, exc_val=None, exc_val=None, Exc_tbs =None): print(" exit ") self.f.close()Copy the code

In this case, the File class is a context manager

We use the File class to write to the File using the with statement and the try/finally statement, respectively

Execute with the with statement:

With File('file.txt', 'w') as f: print( ) f.write('Hello')Copy the code

Console output:

Enter writing... exitCopy the code

And you get a file called file.txt with Hello

Execute with a try/finally statement:

ContextManager = File('file.txt', 'w') VAR = contextManager.__enter__ () try: print(" writing..." ) VAR.write('Hello') finally: ContextManager.__exit__()Copy the code

Console output:

Enter writing... exitCopy the code

And you get a file called file.txt with Hello

The output of the two is consistent, so the equivalence relation of the execution process in the second is verified to be correct

__enter__ and __exit__ methods

1, __enter__ method description

The context manager’s __enter__ method can return a value. By default, it returns None. The as… With EXPR as VAR assigns the return value of the EXPR object’s __enter__ method to VAR.

Of course with… as… Use alone with… The context manager’s __enter__ method still works, except that the return value is not assigned to a variable, and the code block below with cannot use the return value.

2, __exit__ method description

The context manager’s __exit__ method accepts three arguments exc_type, exc_val, and exc_tb, which are type(e), STR (e), and e.__traceback__ if the code BLOCK exits with an exception E, or None otherwise.

The __exit__ method can also return a value, which should be a Boolean True or False, default to None (False). If False, the exception is thrown and the user needs to handle the exception. If True, the exception is ignored.

Contextmanager decorator

Python also provides a contextmanager decorator that allows the user to define a generator as a contextmanager. The decorator splits the code in the generator into two parts using the yield statement, preceded by the __enter__ method, The code after yield is the __exit__ method. The return value of yield is the return value of the __enter__ method, which is assigned to the variable after AS.

Here we also implement a contextmanager for a file using the contextmanager decorator:

from contextlib import contextmanager @contextmanager def open_file(filename, mode): Print (' enter ') f = open(filename, mode) try: yield f finally: print(' exit ') f.close()Copy the code

Use try/except/finally to ensure that the file will be closed properly even if an exception occurs during the yield process.

Execute with the with statement:

With open_file (' file. TXT ', 'w') as f: print (" is written to..." ) f.write('Hello')Copy the code

The execution results match the previous contextmanager execution results, indicating that the contextmanager decorator can also define a contextmanager.

The contextmanager is an object that implements the __enter__ and __exit__ methods internally, so if you are interested in the contextmanager decorator, you can look at the source of the contextmanager decorator and see how it turns a generator into a contextmanager. The contextManager decorator is the contextManager decorator that processes the generator into an object that internally implements __enter__ and __exit__ methods.

Six, summarized

  1. The with statement is an alternative to the try/finally statement, simplifying cleanup after resource calls
  2. The with statement operates on the context manager, which is implemented internally__enter__and__exit__Method object
  3. __enter__Methods can take a return value, which is passed with… The as… As in the statement is assigned to the variable following it;__exit__Returns a Boolean value. If False, the exception is thrown and the user needs to handle the exception. If True, the exception is ignored
  4. Python also provides the contextmanager decorator, which further simplifies the definition of the contextmanager by processing the generator into an internal implementationEnter__ ` and ` __exitMethod to implement the generator variable-context manager

Python Chinese community as a decentralized global technology community, to become the world’s 200000 Python tribe as the vision, the spirit of Chinese developers currently covered each big mainstream media and collaboration platform, and ali, tencent, baidu, Microsoft, amazon and open China, CSDN industry well-known companies and established wide-ranging connection of the technical community, Have come from more than 10 countries and regions tens of thousands of registered members, members from the Ministry of Public Security, ministry of industry, tsinghua university, Beijing university, Beijing university of posts and telecommunications, the People’s Bank of China, the Chinese Academy of Sciences, cicc, huawei, BAT, represented by Google, Microsoft and other government departments, scientific research institutions, financial institutions, and well-known companies at home and abroad, nearly 200000 developers to focus on the platform.

Python Chinese community public account bottom reply “internal push”

Get a weekly list of technical positions to be promoted

******▼ Click below **** to read the original article and become a free member of ** community