- With statement
- Context Manager
- Contextlib Module
- Reference reference
With statement
A new statement that appears in Python2.6 with the WITH statement. Before Python2.6, to properly handle resource management involving exceptions, you would need to use the Try/finally code structure. If you want to enable the file to close correctly when the operation is abnormal, you need to implement the following as follows:
f = open ("test.txt")try: for in F.readlines (): print(line)finally: f.close ()
The finnally statement in the try/finally executes regardless of whether the file operation has an exception, ensuring that the file is closed correctly. However, it is clear that Python's designers are not satisfied with this, they are in the hope of a more concise and graceful form to achieve the cleanup of resources, and hope that this cleanup work does not need to be exposed to the user, so there is a with statement.
The basic syntax structure of the WITH statement is as follows:
with expression [as variable]:with-block
Let's take a look at the example of using the WITH statement instead of the above try/finally, and then discuss it in more detail, as follows
With open ("text.txt") as F: for in F.readlines ()
Print (line)
It is not found that using the WITH statement is a lot simpler than try/finally, and it does not require every user to write F.close () to close the file because the WITH statement does a lot of work behind it. The expression of the With statement is the context manager, which we will say later. The [as variable] in the WITH statement is optional, and if the as variable specifier is specified, variable is the object returned by the context manager expression call __enter__ () function. So, F is not necessarily the expression, but the return value of expression.__enter__ (), and what expression.__enter__ () returns is determined by this function. With-block is the execution statement, when the With-block execution completes, the WITH statement will automatically clean up the resource, corresponding to the above example is the WITH statement will automatically close the file.
Let's go through the details of what the WITH statement has done in the background of obscurity. We just said it. expression is a context manager that implements the __enter__ and __exit__ two functions. When we invoke a with statement, the following procedure is performed:
1. First generate a context manager expression, in the above example with the statement first with "Test.txt" as a parameter to generate a context manager open ("Test.txt").
2. Then execute expression.__enter__ (). If the [as variable] specifier is specified, the return value of __enter__ () is assigned to variable. In the example above, open ("test.txt"). __ENTER__ () Returns a file object to F.
3. Execute the WITH-BLOCK statement block. The read file is executed in the previous example.
4. Execute expression.__exit__ () and the resource cleanup work can be done in the __exit__ () function. In the example above, the execution of the file is closed.
The WITH statement can not only manage files, but also manage locks, connections, and so on, as in the following example:
# Manage Locks Import = Threading.lock () with Lock: # perform some operation pass
Context Manager
In the preceding section we refer to the context manager in the WITH statement. The WITH statement can be so simple but powerful that it relies primarily on the context manager. So what is a context manager? The context manager is the class that implements the context protocol, and the context protocol is a class that implements __ENTER__ () and __exit__ () two methods. As long as a class implements __ENTER__ () and __exit__ (), we call it the context manager.
__enter__ (): primarily performs some environment preparation and returns a resource object. If the context Manager open ("Test.txt") the __enter__ () function returns a file object.
__exit__ (): The full form is __exit__ (type, value, Traceback), the three parameters and the return value of the call Sys.exec_info () function are the same, respectively, exception type, exception information, and stack. If the execution body statement does not throw an exception, all three parameters are set to none. Otherwise, they will contain the exception information for the context. The __exit_ () method returns True or false, indicating whether the exception being thrown is handled, and if False, the exception that is thrown is passed out of context. If an exception is thrown inside the __exit__ () function, the exception that is thrown in the execution is overwritten. When handling an exception, you do not need to re-throw the exception, only the return False,with statement will detect __exit__ () to return false to handle the exception.
If we want to customize a context manager, we just need to define a class and implement __enter__ () and __exit__ (). The following is a simple example of a demo if you create a new custom context manager, let's take a database connection as an example. When working with a database, there are sometimes transactional operations involved. Transaction operations for a database when a commit () execution SQL command is called, if execution fails during this process, the rollback () rollback of the database is required and is typically implemented in the following way:
def test_write (): = mysqldb.connection () = con.cursor () "" " #具体的sql语句 " " " try: cursor.execute (SQL) cursor.execute (SQL) cursor.execute (SQL) Con.commit () #提交事务 except Exception as ex: Con.rollback () #事务执行失败, rollback database
If you want to use the WITH statement to implement a database execution failed rollback operation, then we need to customize a database connection context manager, if dbconnection, then we will use the above example with the statement to implement, it should be this way, as follows:
def test_write (): """ #具体的sql语句 " "= DBConnection () with con as cursor: Cursor.execute (SQL) cursor.execute (SQL) cursor.execute (SQL)
To implement the functionality of the WITH statement above, our DbConnection database context Manager needs to provide functionality: __enter__ () to return a connected cursor; When no exception occurs, the __exit__ () function commits all database operations. If an exception occurs, _exit__ () rolls back the database and calls rollback (). So we can implement DbConnection as follows:
1 defDBConnection (object):2 def __init__(self):3 Pass4 5 defcursor (self):6 #returns a cursor and initiates a transaction7 Pass8 9 defcommit (self):Ten #commit the current transaction One Pass A - defrollback (self): - #rolling back the current transaction the Pass - - def __enter__(self): - #returns a cursor +cursor =self.cursor () - returncursor + A def __exit__(self, type, value, TB): at ifTb isNone: - #commit the transaction without exception - Self.commit () - Else: - #Rollback Database If there is an exception -Self.rollback ()
Python learning notes with statement vs. Context Manager