SoFunction
Updated on 2025-05-06

In-depth and easy-to-understand examples in Python

1. What is a with statement?

withStatements are syntactic sugars used in Python to simplify resource management. It ensures that the resource is automatically fetched when entering the code block and automatically frees the resource when exiting the code block. Common resources include files, network connections, database connections, etc.withThe core idea of ​​the statement is "context management", that is, automatically handle the acquisition and release of resources within a certain range, avoiding the complexity and potential errors caused by manual management of resources.

1.1 Context Manager

withStatements depend onContext Manager(Context Manager), this is an implementation__enter__and__exit__Object of method.__enter__The method is enteringwithCalled when code blocks are usually used to obtain resources;__exit__Method is exitingwithCalled when code blocks are usually used to free resources.

1.2 Basic syntax of with statements

withThe basic syntax of a statement is as follows:

with context_manager as variable:
    # Execute code blocks

in,context_managerIt is an object that implements the context management protocol.variableis optional for receiving__enter__The value returned by the method.

1.3 Advantages of with statements

  • Automatic resource managementwithThe statement ensures that the resource is automatically released after use, and even if an exception occurs in the code block, it can ensure that the resource is released correctly.
  • Concise code: Compared to the way of manually managing resources,withStatements can reduce redundant code and make the code more concise and easy to read.
  • Exceptionally safe: Even if an exception is thrown in the code block,withThe statement will also ensure__exit__Methods are called to avoid resource leakage.

2. Common usage of with statements

2.1 File Operation

File operations are the most commonwithOne of the sentence application scenarios. passwithThe statement opens the file and can be automatically closed after the file is used without explicit calls.close()method.

Example: Read file content

with open('', 'r') as file:
    content = ()
    print(content)

In this example,open()The function returns a file object that implements the context management protocol.withStatements ensure that they are automatically called at the end of the code block.(), the file will be closed correctly even if an exception occurs while reading the file.

Example: Write file contents

with open('', 'w') as file:
    ("Hello, World!")

same,withStatements ensure that the file is automatically closed after writing, avoiding forgetting to call.close()The problem.

2.2 Network connection

In network programming,withStatements can be used to manage network connections to ensure that the connection is automatically closed after use. For example, userequestsWhen the library sends HTTP requests, it can be passedwithStatement management session (Session) objects.

Example: Send HTTP requests using requests

import requests

with () as session:
    response = ('/data')
    print(())

In this example,SessionThe object will bewithThe code block is automatically closed at the end to ensure that the resource is released correctly.

2.3 Database connection

In database operations,withStatements can be used to manage database connections to ensure that the connection is automatically closed after use. For example, usesqlite3When the library connects to the SQLite database, it can be passedwithStatement manages connection objects.

Example: Use sqlite3 to connect to the database

import sqlite3

with ('') as conn:
    cursor = ()
    ('SELECT * FROM users')
    rows = ()
    for row in rows:
        print(row)

In this example,connect()The function returns a database connection object that implements the context management protocol.withStatements ensure that they are automatically called at the end of the code block.(), the connection is closed correctly even if an exception occurs while executing a SQL query.

2.4 Locking mechanism

In multithreaded programming,withStatements can be used to manage locks (Locks) to ensure that the lock is automatically released after use. For example, useWhen, you can passwithStatement management lock objects.

Example: Use and implement thread synchronization

import threading

lock = ()

def thread_function():
    with lock:
        print(f"Thread {threading.current_thread().name} is running")

threads = []
for i in range(5):
    t = (target=thread_function, name=f"Thread-{i+1}")
    (t)
    ()

for t in threads:
    ()

In this example,lockThe object will bewithAutomatically release at the end of the code block, ensuring that multiple threads do not access shared resources at the same time, thereby avoiding race conditions.

2.5 Custom context manager

In addition to the built-in context manager, you can also implement it__enter__and__exit__Methods customize context manager. This makeswithStatements can be used in a wider range of application scenarios.

Example: Custom context manager

Suppose we want to create a context manager to record the execution time of a certain block of code. We can define a classTimer, and implement it in it__enter__and__exit__method.

import time

class Timer:
    def __enter__(self):
        self.start_time = ()
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        end_time = ()
        elapsed_time = end_time - self.start_time
        print(f"Elapsed time: {elapsed_time:.2f} seconds")

# Use a custom context managerwith Timer():
    (2)

In this example,TimerClass implements a context management protocol.__enter__Method records the start time,__exit__Method calculates and prints the elapsed time.withStatements ensure that they are automatically called at the end of the code block.__exit__Method, thereby achieving accurate measurement of code block execution time.

2.6 UsecontextlibModule

Python'scontextlibModules provide some convenient tools that can help us create context managers more easily. The most commonly used one is@contextmanagerDecorator, which can convert normal functions into context managers.

Example: Create a context manager using @contextmanager

Suppose we want to create a context manager to temporarily change the current working directory. We can use@contextmanagerDecorators to achieve this.

from contextlib import contextmanager
import os

@contextmanager
def change_directory(path):
    current_dir = ()
    (path)
    try:
        yield
    finally:
        (current_dir)

# Use a custom context managerwith change_directory('/tmp'):
    print(())  # Output /tmp
print(())  # Output the original directory

In this example,change_directoryFunctions are@contextmanagerDecorator wrappers, making it a context manager.yieldThe previous code is enteringwithExecute code blocks,yieldThe subsequent code is exitingwithExecute when blocking code.finallyThe block ensures that the original working directory is restored regardless of whether an exception occurs or not.

3. Advanced usage of with statements

3.1 Multiple context managers

withStatements support the management of multiple context managers simultaneously, just separate them with commas. This is very useful for scenarios where multiple resources need to be managed simultaneously.

Example: Manage multiple files simultaneously

Suppose we need to read the contents of two files at the same time and compare them. We can usewithStatements manage two file objects at the same time.

with open('', 'r') as f1, open('', 'r') as f2:
    content1 = ()
    content2 = ()
    if content1 == content2:
        print("Files are identical")
    else:
        print("Files are different")

In this example,withStatements manage two file objects at the same time.f1andf2, make sure they are automatically closed at the end of the code block.

3.2 Exception handling

withStatements can not only manage resources, but also catch and handle exceptions.__exit__The method can accept three parameters:exc_typeexc_valueandtraceback, respectively represent the exception type, outlier value and stack trace. if__exit__Method returnTrue, it means that the exception has been processed and will not propagate to the outside; if returnedFalseor no value is returned, the exception will continue to propagate.

Example: Catch exceptions

Suppose we want to capture and process during file readingFileNotFoundErrorException. We can implement this in a custom context manager.

class FileOpener:
    def __init__(self, filename):
         = filename
         = None

    def __enter__(self):
        try:
             = open(, 'r')
            return 
        except FileNotFoundError:
            print(f"File {} not found")
            return None

    def __exit__(self, exc_type, exc_value, traceback):
        if :
            ()

# Use a custom context managerwith FileOpener('') as file:
    if file:
        content = ()
        print(content)
    else:
        print("File not found, skipping...")

In this example,FileOpenerClass is__enter__Try to open the file in the method and captureFileNotFoundErrorException. If the file does not exist, it prints a message and returnsNone, instead of throwing an exception.__exit__Methods ensure that the file is automatically closed after use.

3.3 

yescontextlibAn advanced tool in the module that allows you to dynamically add multiple context managers at runtime. This is very useful for scenarios where different resources need to be managed according to conditions.

Example: Dynamic management of resources using ExitStack

Suppose we have a function that decides whether to open a file or create a temporary directory based on the passed parameters. We can useExitStackTo dynamically manage these resources.

from contextlib import ExitStack, contextmanager
import tempfile

def process_resources(open_file=True, create_temp_dir=False):
    with ExitStack() as stack:
        resources = []
        if open_file:
            file = stack.enter_context(open('', 'r'))
            (file)
        if create_temp_dir:
            temp_dir = stack.enter_context(())
            (temp_dir)
        return resources

# Use the `process_resources` functionresources = process_resources(open_file=True, create_temp_dir=True)
for resource in resources:
    print(resource)

In this example,ExitStackAllows us to dynamically add context managers according to conditions at runtime.enter_contextMethods Add context manager toExitStackand make sure they are inwithThe code block will be automatically closed when the end of the code block.

4. Summary

withStatements are a very powerful and flexible feature in Python that can help us simplify resource management and ensure that resources are automatically released after use. By combining the context manager,withStatements can not only be used for common file operations, network connections and database connections, but also for more complex scenarios such as locking mechanisms, custom resource management and exception handling.

Review of key points

  • withThe statement depends on the context manager, which implements the__enter__and__exit__method.
  • withStatements ensure that resources are automatically released after use, avoiding the complexity and potential errors caused by manual management of resources.
  • withStatements can be used in a variety of resource management scenarios, such as file operations, network connections, database connections, locking mechanisms, etc.
  • You can achieve__enter__and__exit__Methods customize context managers, or usecontextlibConvenient tools provided by the module.
  • withStatements support the management of multiple context managers simultaneously and can catch and handle exceptions.

5. References

  • Python official documentation - context manager
  • Python official documentation - contextlib module

This is all about this article about with statements in Python. For more related Python with statement content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!