Home Backend Development Python Tutorial How to use Python's with statement

How to use Python's with statement

May 25, 2023 pm 05:22 PM
python with

Statement body (with-body): The code block wrapped in the with statement will call the enter() method of the context manager before executing the statement body, and the exit() method will be executed after the statement body is executed.

 Basic syntax and working principle

 The syntax format of the with statement is as follows:

 Listing 1. Syntax format of the with statement

 with context_expression [as target(s)]:

 with-body

 Here contextexpression returns a context manager object, which is not assigned to the as clause In target(s), if the as clause is specified, the return value of the context manager's _enter() method will be assigned to target(s). target(s) can be a single variable, or a tuple enclosed by "()" (it cannot be a list of variables separated only by ",", "()" must be added).

Python has improved some built-in objects and added support for context managers, which can be used in with statements, such as automatically closing files, automatically acquiring and releasing thread locks, etc. Suppose you want to operate a file, you can use the with statement to have the following code:

 Listing 2. Use the with statement to operate the file object

 with open(r'somefileName' ) as somefile:

 for line in somefile:

 print line

 # ...more code

 The with statement is used here, no matter what is being processed Whether an exception occurs during the file process, it can be ensured that the open file handle has been closed after the with statement is executed. If you use the traditional try/finally paradigm, you need to use code similar to the following:

 Listing 3. Try/finally mode to operate file objects

 somefile = open(r' somefileName')

try:

for line in somefile:

print line

# ...more code

finally:

 somefile.close()

In comparison, using the with statement can reduce the amount of coding. Modules threading, decimal, etc. have also been added to support the context management protocol.

PEP 0343 describes the implementation of the with statement. The execution process of the with statement is similar to the following code block:

 Listing 4. The execution process of the with statement

 context_manager = context_expression

 exit = type(context_manager) .__exit__

Value = type(context_manager).__enter__(context_manager)

exc = True # True means normal execution, even if there is an exception, it will be ignored; False means re-throwing the exception, and the exception needs to be treated Process

try:

try:

target = value # If the as clause is used

with-body #Execute with-body

 except: # An exception occurs during execution

 exc = False

 # If __exit__ returns True, the exception is ignored; if it returns False, the exception is re-thrown

 #Exception handling by outer code

if not exit(context_manager, *sys.exc_info()):

raise

finally:

 #Exit normally, or exit through the break/continue/return statement in the statement-body

 #Or ignore the exception and exit

 if exc:

 exit (context_manager, None, None, None)

 # Returns None by default, None is regarded as False in a Boolean context

 Execute context_expression to generate the context manager context_manager.

Call the enter() method of the context manager; if the as clause is used, assign the return value of the enter() method to the target(s) in the as clause.

 Execution statement body with-body

Regardless of whether an exception occurs during execution, the exit() method of the execution context manager is executed. The exit() method is responsible for execution. "Cleaning" work, such as releasing resources, etc. If no exception occurs during execution, or the statement break/continue/return is executed in the statement body, call exit(None, None, None) with None as the parameter; if an exception occurs during execution, use sys.excinfo The exception information is the parameter call _exit(exc_type, exc_value, exc_traceback).

When an exception occurs, if exit(type, value, traceback) returns False, the exception will be re-thrown and the statement logic other than with will be used to handle the exception. This is also a common practice; if it returns True, then Ignore the exception and no longer handle the exception.

 Custom context manager

Developers can customize classes that support the context management protocol. The custom context manager needs to implement the enter() and exit() methods required by the context management protocol:

Contextmanager._enter(): Enter the runtime context of the context manager and execute it in the statement body Called before. The with statement assigns the method's return value to the target in the as clause, if one is specified.

Contextmanager._exit(exc_type, exc_value, exc_traceback): Exits the runtime context related to the context manager and returns a Boolean value indicating whether to handle the exception that occurred. The parameters indicate the exception that caused the exit operation. If no exception occurs during exit, all three parameters are None. If an exception occurs, return.

 True means not to handle the exception, otherwise the exception will be re-thrown after exiting the method to be handled by code logic outside the with statement. If an exception is raised within this method, it will replace the exception raised by the statement in statement-body. When handling an exception, do not explicitly rethrow the exception, that is, you cannot rethrow the exception passed in through the parameters. You only need to set the return value to False. The context management code then detects whether exit() failed to handle the exception.

The following is a simple example to demonstrate how to build a custom context manager. Note that the context manager must provide definitions for both the enter() and exit() methods, the absence of either will result in an AttributeError; the with statement first checks whether the exit() method is provided, and then checks whether the enter() method is defined.

Suppose there is a resource DummyResource. This resource needs to be allocated before accessing and released after use. The allocation operation can be placed in the enter() method, and the release operation can be placed in the exit() method. . For the sake of simplicity, only print statements are used to indicate the current operation, and there is no actual resource allocation and release.

 Listing 5. Custom objects that support the with statement

 class DummyResource:

 def __init__(self, tag):

Self.tag = tag

print 'Resource [%s]' % tag

def __enter__(self):

print '[Enter %s]: Allocate resource .' % self.tag

Return self # Different objects can be returned

def __exit__(self, exc_type, exc_value, exc_tb):

print '[Exit %s ]: Free resource.' % self.tag

if exc_tb is None:

print '[Exit %s]: Exited without exception.' % self.tag

else:

 print '[Exit %s]: Exited with exception raised.' % self.tag

 return False # Can be omitted, the default None is also regarded as False

Enter() in DummyResource returns a reference to itself, which can be assigned to the target variable in the as clause; the type of the return value can be set to a different type according to actual needs, and does not have to be a context manager object. itself.

The variable exctb is detected in the exit() method. If it is not None, it means that an exception has occurred. Returning False means that the exception needs to be handled by external code logic; note that if no exception occurs, the default The return value is None, which is also regarded as False in a Boolean environment. However, since no exception occurs, the three parameters of _exit() are None. The context management code can detect this situation and handle it normally.

The following is to access DummyResource in the with statement:

Listing 6. Using a custom object that supports the with statement

with DummyResource('Normal' ):

 print '[with-body] Run without exceptions.'

 with DummyResource('With-Exception'):

 print '[with-body] Run with exception.'

 raise Exception

 print '[with-body] Run with exception. Failed to finish statement-body!'

 Execution of the first with statement The results are as follows:

 Listing 7. With statement 1 execution result

 Resource [Normal]

 [Enter Normal]: Allocate resource.

 [with-body] Run without exceptions.

 [Exit Normal]: Free resource.

 [Exit Normal]: Exited without exception.

 You can see , during normal execution, the statement body with-body will be executed first, and then the exit() method will be executed to release resources.

The execution result of the second with statement is as follows:

Listing 8. The execution result of with statement 2

Resource [With-Exception]

 [Enter With-Exception]: Allocate resource.

 [with-body] Run with exception.

 [Exit With-Exception]: Free resource.

[Exit With-Exception]: Exited with exception raised.

Traceback (most recent call last):

File "G:/demo", line 20, in raise Exception

 Exception

It can be seen that when an exception occurs in with-body, with-body has not been executed, but the resources are guaranteed to be released. At the same time, the exception generated is caused by the code logic outside the with statement. capture processing.

You can customize the context manager to manage resources in the software system, such as database connections, access control of shared resources, etc. The Python online documentation Writing Context Managers provides a simple example of a context manager for managing database connections.

Contextlib module

The contextlib module provides three objects: the decorator contextmanager, the function nested and the context manager closing. Using these objects, you can wrap existing generator functions or objects and add support for the context management protocol, avoiding the need to write a context manager specifically to support the with statement.

Decorator contextmanager

Contextmanager is used to decorate the generator function. After the generator function is decorated, a context manager is returned, and its enter() and exit() methods are The contextmanager is responsible for providing it instead of the previous iterator. The decorated generator function can only produce one value, otherwise it will cause an exception RuntimeError; the generated value will be assigned to the target in the as clause, if the as clause is used. Let's look at a simple example.

 List 9. Decorator contextmanager usage example

 from contextlib import contextmanager

 @contextmanager

 def demo():

 print '[Allocate resources]'

 print 'Code before yield-statement executes in __enter__'

 yield '*** contextmanager demo ***'

 print 'Code after yield-statement executes in __exit__'

 print '[Free resources]'

 with demo() as value:

 print 'Assigned Value: %s' % value

The result output is as follows:

Listing 10. Contextmanager usage example execution result

[Allocate resources]

 Code before yield-statement executes in __enter__

 Assigned Value: *** contextmanager demo ***

 Code after yield-statement executes in __exit__

 [Free resources]

It can be seen that the statement before yield in the generator function is executed in the enter() method, the statement after yield is executed in exit(), and the value generated by yield is assigned to the as clause. value variable.

It should be noted that the contextmanager only omits the writing of enter() / exit(), but is not responsible for the "acquisition" and "cleaning" of resources; the "acquisition" operation needs to be defined in the yield statement Previously, the "cleaning" operation needed to define the yield statement, so that the with statement would execute these statements to obtain/release resources when executing the enter() / exit() method, that is, the necessary logic control, including resources, needed to be implemented in the generator function Throw appropriate exceptions when access errors occur.

 Function nested

Nested can organize multiple context managers together to avoid using nested with statements.

 Listing 11. nested syntax

 with nested(A(), B(), C()) as (X, Y, Z):

 #with-body code here

 Similar to:

 Listing 12. nested execution process

 with A() as X:

 with B() as Y:

 with C() as Z:

 # with-body code here

It should be noted that an exception occurs Finally, if a context manager's exit() method returns False for exception handling, the outer context manager will not detect the exception.

 Context manager closing

The implementation of closing is as follows:

 Listing 13. Context management closing implementation

class closing(object):

# help doc here

def __init__(self, thing):

self.thing = thing

def __enter__(self):

return self.thing

def __exit__(self, *exc_info):

self.thing.close()

Context The manager will assign the wrapped object to the target variable of the as clause, and ensure that the opened object will be closed after with-body is executed. The object wrapped by the closing context manager must provide the definition of the close() method, otherwise an AttributeError will be reported during execution.

 Listing 14. Custom objects that support closing

 class ClosingDemo(object):

 def __init__(self):

 self.acquire()

  def acquire(self):

 print 'Acquire resources.'

  def free(self):

 print ' Clean up any resources acquired.'

def close(self):

self.free()

with closing(ClosingDemo()):

print 'Using resources'

The result output is as follows:

Listing 15. Output result of custom closing object

Acquire resources.

Using resources

Clean up any resources acquired.

Closing is applicable to objects that provide close() implementation, such as network connections, database connections, etc. It can also be passed when customizing classes. Interface close() to perform the required resource "cleaning" work.

The above is the detailed content of How to use Python's with statement. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

HadiDB: A lightweight, horizontally scalable database in Python HadiDB: A lightweight, horizontally scalable database in Python Apr 08, 2025 pm 06:12 PM

HadiDB: A lightweight, high-level scalable Python database HadiDB (hadidb) is a lightweight database written in Python, with a high level of scalability. Install HadiDB using pip installation: pipinstallhadidb User Management Create user: createuser() method to create a new user. The authentication() method authenticates the user's identity. fromhadidb.operationimportuseruser_obj=user("admin","admin")user_obj.

Navicat's method to view MongoDB database password Navicat's method to view MongoDB database password Apr 08, 2025 pm 09:39 PM

It is impossible to view MongoDB password directly through Navicat because it is stored as hash values. How to retrieve lost passwords: 1. Reset passwords; 2. Check configuration files (may contain hash values); 3. Check codes (may hardcode passwords).

The 2-Hour Python Plan: A Realistic Approach The 2-Hour Python Plan: A Realistic Approach Apr 11, 2025 am 12:04 AM

You can learn basic programming concepts and skills of Python within 2 hours. 1. Learn variables and data types, 2. Master control flow (conditional statements and loops), 3. Understand the definition and use of functions, 4. Quickly get started with Python programming through simple examples and code snippets.

How to optimize MySQL performance for high-load applications? How to optimize MySQL performance for high-load applications? Apr 08, 2025 pm 06:03 PM

MySQL database performance optimization guide In resource-intensive applications, MySQL database plays a crucial role and is responsible for managing massive transactions. However, as the scale of application expands, database performance bottlenecks often become a constraint. This article will explore a series of effective MySQL performance optimization strategies to ensure that your application remains efficient and responsive under high loads. We will combine actual cases to explain in-depth key technologies such as indexing, query optimization, database design and caching. 1. Database architecture design and optimized database architecture is the cornerstone of MySQL performance optimization. Here are some core principles: Selecting the right data type and selecting the smallest data type that meets the needs can not only save storage space, but also improve data processing speed.

Python: Exploring Its Primary Applications Python: Exploring Its Primary Applications Apr 10, 2025 am 09:41 AM

Python is widely used in the fields of web development, data science, machine learning, automation and scripting. 1) In web development, Django and Flask frameworks simplify the development process. 2) In the fields of data science and machine learning, NumPy, Pandas, Scikit-learn and TensorFlow libraries provide strong support. 3) In terms of automation and scripting, Python is suitable for tasks such as automated testing and system management.

How to use AWS Glue crawler with Amazon Athena How to use AWS Glue crawler with Amazon Athena Apr 09, 2025 pm 03:09 PM

As a data professional, you need to process large amounts of data from various sources. This can pose challenges to data management and analysis. Fortunately, two AWS services can help: AWS Glue and Amazon Athena.

How to start the server with redis How to start the server with redis Apr 10, 2025 pm 08:12 PM

The steps to start a Redis server include: Install Redis according to the operating system. Start the Redis service via redis-server (Linux/macOS) or redis-server.exe (Windows). Use the redis-cli ping (Linux/macOS) or redis-cli.exe ping (Windows) command to check the service status. Use a Redis client, such as redis-cli, Python, or Node.js, to access the server.

Can mysql connect to the sql server Can mysql connect to the sql server Apr 08, 2025 pm 05:54 PM

No, MySQL cannot connect directly to SQL Server. But you can use the following methods to implement data interaction: Use middleware: Export data from MySQL to intermediate format, and then import it to SQL Server through middleware. Using Database Linker: Business tools provide a more friendly interface and advanced features, essentially still implemented through middleware.

See all articles