[python] context manager

Keywords: Database less MySQL

What is context manager

In short, the purpose of the context manager is to specify the scope of use of the object. If it is out of the scope, take the corresponding "processing"; for example:

f = open('filename.txt')
data = f.read()
f.close()

Open a file, read the contents of the file, and close the file. In normal business, it's not enough to write like this, because there may be errors when operating resources. In order to strengthen the code robustness, it needs to be changed frequently as follows:

try:
    f = open('filename.txt')
    data = f.read()
except:
    pass
finally:
    f.close()

No matter what error occurs, close and release the resource f.close() finally. In order to make the code more readable and less error prone, with will be used to implement the context manager:

with open('filename.txt') as f:
    data = f.read()

First, clear up some concepts:

1. Context expression: with open('filename.txt') as f:2. Context manager: open('filename.txt')3. f is not a context manager, but a resource object. It is the object returned by the context manager

Implement context manager

To implement such a context management, you need to know the context management protocol first. In short, in a class, the methods of "enter" and "exit" are implemented. The instance of this class is a context manager. ​​​​​​​

class MyResource:
    def __enter__(self):
        print('opening resource......')
        return self

    def operate(self):
        print('doing something......')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('closing resource......')


with MyResource() as r:
    r.operate()

When the resource is opened, enter the ﹣ enter ﹣ method, and the return object will be assigned to the as object, i.e. the return self object will be assigned to r; no matter whether there is an error or not, after executing the with code block, you will enter the ﹣ exit ﹣ method. If there is an error, the parameter of ﹣ exit ﹣ will be assigned.

Business actual combat

The implementation of a context manager connecting mysql database is based on the above code

import pymysql


class MyResource:
    
    def __init__(self, database):
        self.database = database
    
    def __enter__(self):
        self.conn = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            password='xxxxxx',
            database=self.database,
            charset='utf8'
        )
        self.cursor = self.conn.cursor()
        return self.cursor

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.conn.commit()
        self.cursor.close()
        self.conn.close()


with MyResource('datatbase') as db:
    db.execute('update test set name="rhys" where id=1')

Instantiate the MyResource object with with with, enter the enter function to connect to the database, return the cursor cursor to DB, db.execute for update operation, enter the exit function when exiting the with code block, perform the commit operation, and then close the cursor and connection.

Context manager implements context manager

There is another way to implement a up and down manager, which is to use the contextmanager decorator in contextlib:

from contextlib import contextmanager
import pymysql


@contextmanager
def mysqldb(database):
    try:
        conn = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            password='xxxxxx',
            database=database,
            charset='utf8'
        )
        cursor = conn.cursor()
        yield cursor
        conn.commit()
    except Exception as e:
        print(e)
    finally:
        cursor.close()
        conn.close()


with mysqldb('database') as db:
    db.execute('update test set name="rhys" where id=1')

The function decorated by the contextmanager will become a context manager. Use yield to return the cursor to the db after as. When the update operation is finished, exit the with code block, return to the yield position, and execute the subsequent code.

I prefer to use content manager to implement the query manager. The code is easier to write and understand.

 

Pay attention to the official account: everyday bug, suitable for people who accumulate skills and learn technology by trivial time.

114 original articles published, 44 praised, 110000 visitors+
Private letter follow

Posted by quimkaos on Wed, 11 Mar 2020 00:16:17 -0700