Home  >  Article  >  Backend Development  >  Demystifying the with keyword in Python

Demystifying the with keyword in Python

PHPz
PHPzforward
2023-04-14 11:31:061167browse

Demystifying the with keyword in Python

Many of us have seen this code snippet over and over again in Python code:

with open('Hi.text', 'w') as f:
f.write("Hello, there")

However, some of us don’t know what with and why we need to use it here. In this read, you'll find out about almost any problem that can be solved with. let's start!

First, let’s think about what we need to do without using the with keyword. In this case we need to open the file first and try to write. Regardless of success or failure, we'd better close it at the end, so our code will look like this:

f = open('Hi.text', 'w')
try:
f.write('Hello, there')
finally:
f.close()

So, what is the use of the with keyword? It just helps shorten our try..finally code to a single with... statement! This is how the with statement is used.

So, what exactly is it? In fact, the with statement itself is nothing special in Python, it is just a feature of the context manager in Python. A context manager, quoted from the official Python documentation, is a way to allow you to allocate and free resources exactly when needed, or simply put: shorten your code snippet when you do something on some resource, which means Then you can define the usage of the with statement yourself!

How do we do this? Well, it's simple, you just need to implement two magic functions: one called __enter__ and the other called __exit__. The first way is to write a class that implements these two functions as shown below:

class My_file:
def __init__(self, fname):
self.fname = fname
def __enter__(self):
self.file = open(self.fname, 'w')
return self.file
def __exit__(self, exc_type, exc_val, exc_trace_back):
if self.file:
self.file.close()

Here, we have created a normal Python class that implements the two magic functions. Note the signatures of these two functions: __enter__ will only accept self , while __exit__ will accept more arguments, the three in the example are the standard form. In this way, we can use it directly:

with My_file('hello.txt') as f:
f.write('hello, world!')

The with statement here will first call __init__ to construct a new object, and then call the __enter__ method; finally, it will trigger the __exit__ method before the code block is completed. So, the rough equivalent of the above code is as follows:

myfile = My_file('hello.txt')
f = myfile.__enter__()
f.write('hello, world!')
myfile.__exit(...)

The second way to implement a context manager is through a decorator, as follows:

  1. You import contextmanager from contextlib
  2. You write a function to implement the with statement you want.
  3. Add a decorator @contextmanager above the function.
  4. Use your with your_function!

According to the above introduction, let us write a decorator context manager!

from contextlib import contextmanager
@contextmanager
def my_file_open(fname):
try:
f = open(fname, 'w')
yield f
finally:
print('Closing file')
f.close()
with file_open('hi.txt') as f:
f.write('hello world')

The above pretty much covers all the basics of with statements and context managers, but if you want to learn more, keep going...!

There are some handy tools in contextlib for you to use. The first one is closing . closing basically wraps your block of code with another function that you implement before exiting.

@contextmanager
def closing(f):
try:
f.write("Finish writing")
finally:
f.close()
with closing(open("hi.text")):
f.write("hello world")

For example, in the above code, we can directly call close(your_way_of_getting_resource), and before the code block you write below is about to complete (f.write("hello world")), it will execute try ..finally block we defined above.

The other is to use the suppress tool. We know that in many cases, if we try to get some resources, it is likely that errors such as FileNotFoundException will occur when opening the file. In some cases we want to catch errors or suppress them so that the program can continue to run normally. suppress is one way we can suppress warnings. All you need to do is figure out which exception you want to suppress and write with suppress(your_choice_of_exception) and Python will handle it from there.

In other cases, you may only want to perform certain actions when entering a with block. In this case, nullcontext will be convenient for you. nullcontext will just return what you defined in the __enter__ function and won't do anything else. If you are dealing with async operations in Python to access resources, aclosure is a utility for handling this situation.

Summary

This article introduces some basic concepts and usage of the with statement and its underlying working principle. There's lots more interesting stuff, check out Python's contextlib documentation. Finally, I wish you the same happy learning and happy coding as always!

The above is the detailed content of Demystifying the with keyword in Python. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:51cto.com. If there is any infringement, please contact admin@php.cn delete