Python: comment utiliser async avec

Comment utiliser async avec qui peut être utilisé à partir de python 3.5. PEP 492 -- Coroutines with async and await syntax

async with? Une version asynchrone du gestionnaire de contexte.

1.Faites une connexion à DB <-Il faut du temps = async 2. Faites quelque chose avec la connexion que vous avez établie 3. Fermez la connexion

Quand il y a un traitement comme

async with MyDB() as db:
    db.do_something()

Si vous améliorez MyDB en exécutant le code, vous pouvez fermer automatiquement la connexion db lorsque vous quittez l'async avec block.

Utilisation de base

Par exemple, créons une classe qui enveloppe aiomysql et utilisons-la.

my_db.py

my_db.py


import asyncio
import aiomysql


class MyDB:
    #Appelé juste avant d'entrer en mode asynchrone avec.
    async def __aenter__(self):
        loop = asyncio.get_event_loop()
        self._connection = await aiomysql.connect(
            host='localhost',
            port=3306,
            user='root',
            password='ultrastrongpassword',
            db='my_db',
            charset='utf8',
            loop=loop
        )
        return self

    #Appelé immédiatement après avoir quitté l'asynchrone avec bloc.
    async def __aexit__(self, exc_type, exc, tb):
        self._connection.close()

    async def fetchall(self, query, args=[]):
        cursor = await self._connection.cursor()
        await cursor.execute(query, args)
        return await cursor.fetchall()

On a l'impression de cacher la destination de connexion de aiomysql.

Les plus importants sont «aenter» et «aexit». En les implémentant, cette classe peut être utilisée comme gestionnaire de contexte asynchrone. Le moment de l'appel est tel que commenté.

Comme dans l'exemple, aenter est un modèle courant pour configurer des ressources et aexit pour libérer des ressources.

Côté utilisateur

Regardons également l'appelant.

Côté à utiliser


from my_db import MyDB


class Hoge:
    async def call_db(self):
        # db = MyDB()
        # async with db:
        #Mais cela a le même sens.
        async with MyDB() as db:
            result = db.fetchall('select * from some_table')
        print(result)

Le format est ʻasynchronisation avec [instance de gestionnaire de contexte asynchrone] comme [valeur de retour de __aenter __]: `.

Lorsque cela est exécuté, le traitement se déroule dans l'ordre suivant.

  1. Une instance de MyDB est créée (__init__ est appelé)
  2. L'asynchronisation de Hoge avec la clause commence le traitement
  3. MyDB __aenter__ est appelé
  4. La valeur de retour de «aenter» de MyDB est stockée dans la base de données «async with as db»
  5. Le résultat de Hoge = db.fetchall ('select * from some_table') `est exécuté
  6. MyDB __aexit__ est appelé

Il semble qu'une instance de base de données ne pourra utiliser toutes ses ressources que lorsqu'elle est asynchrone avec.

Divers autres usages

Je veux l'utiliser en usine

ʻAsync avec MyDB.connect () as db: `Quand vous voulez

Côté à utiliser


class Hoge:
    async def call_db(self):
        async with MyDB.connect() as db:
            result = db.fetchall('select * from some_table')
        print(result)

Implémentez simplement la méthode de connexion normalement comme suit:

my_db.py


class MyDB:
    __slots__ = ['_connection']

    async def __aenter__(self):
        (Abréviation)

    async def __aexit__(self, exc_type, exc, tb):
        self._connection.close()

    async def fetchall(self, query, args=[]):
        (Abréviation)

    @classmethod
    def connect(cls):
        return cls()

Tout ce dont vous avez besoin est une instance de MyDB (Asynchronous Context Manager) après asynchronisation avec.

Je souhaite m'asynchroniser avec un système qui ne renvoie pas ma propre instance

Côté à utiliser


class Hoge:
    async def call_db(self):
        async with MyDB.direct_fetch('select * from some_table') as rows:
            print(rows)

Dans ce cas, il est peu probable que la valeur de retour de MyDB.direct_fetch dans async with soit dans l'instance MyDB, vous devez donc réfléchir un peu. Get aiohttp peut être utile.

Il peut être géré en créant une classe de gestionnaire de contexte privé comme indiqué ci-dessous.

my_db.py


class _QueryContextManager:
    def __init__(self, coro):
        self._coro = coro

    async def __aenter__(self):
        loop = asyncio.get_event_loop()
        self._connection = await aiomysql.connect(
            host='localhost',
            port=3306,
            user='root',
            password='ultrastrongpassword',
            db='my_db',
            charset='utf8',
            loop=loop
        )
        return await self._coro(self._connection)

    async def __aexit__(self, exc_type, exc, tb):
        self._connection.close()


class MyDB:
    __slots__ = ['_connection']

    @classmethod
    def direct_fetch(cls, query, args=[]):
        async def fetch(connection):
            cursor = await connection.cursor()
            await cursor.execute(query, args)
            return await cursor.fetchall()

        #Renvoie un gestionnaire de contexte privé.
        return _QueryContextManager(coro=fetch)

Hmm. Je ne peux pas nier le sentiment de force. .. Il existe peut-être une meilleure façon de l'écrire.

aiohttp peut fermer la connexion depuis l'instance de la valeur de retour de request (self._resp.release ()), donc cela semble être un peu plus propre.

Recommended Posts

Python: comment utiliser async avec
python3: Comment utiliser la bouteille (2)
[Python] Comment utiliser la liste 1
Comment utiliser Python Argparse
Python: comment utiliser pydub
[Python] Comment utiliser checkio
[Python] Comment utiliser input ()
Comment utiliser Python lambda
[Python] Comment utiliser virtualenv
python3: Comment utiliser la bouteille (3)
python3: Comment utiliser la bouteille
Comment utiliser les octets Python
Comment utiliser tkinter avec python dans pyenv
[Python] Comment utiliser la série Pandas
Comment utiliser les requêtes (bibliothèque Python)
Comment utiliser SQLite en Python
Pour utiliser virtualenv avec PowerShell
Comment utiliser le mode interactif python avec git bash
Comment démarrer avec Python
[Python] Comment utiliser la liste 3 Ajouté
Comment utiliser Mysql avec python
Comment utiliser l'API Python d'OpenPose
Comment utiliser ChemSpider en Python
Python: Comment utiliser pydub (lecture)
Comment utiliser PubChem avec Python
Comment calculer la date avec python
Comment utiliser la fonction zip de python
[Python] Comment utiliser l'API Typetalk
Comment utiliser le wrapper Python PyRealsense de Realsense avec Jetson Nano
[Python] Résumé de l'utilisation des pandas
[Introduction à Python] Comment utiliser la classe en Python?
Comment installer et utiliser pandas_datareader [Python]
Comment utiliser ManyToManyField avec l'administrateur de Django
Comment utiliser OpenVPN avec Ubuntu 18.04.3 LTS
Comment utiliser Cmder avec PyCharm (Windows)
[python] Comment utiliser __command__, explication des fonctions
Comment utiliser BigQuery en Python
[Introduction à Python] Utilisons foreach avec Python
[Python] Comment utiliser import sys sys.argv
Comment utiliser Ass / Alembic avec HtoA
Comment utiliser le japonais avec le tracé NLTK
Comment faire un test de sac avec python
[Python] Organisation de l'utilisation des instructions
Mémorandum sur l'utilisation du python gremlin
Comment afficher le japonais python avec lolipop
[Python2.7] Résumé de l'utilisation d'unittest
Comment utiliser le notebook Jupyter avec ABCI
python: Comment utiliser les locals () et globals ()
Comment utiliser __slots__ dans la classe Python
Comment utiliser la commande CUT (avec exemple)
Comment utiliser "deque" pour les données Python
Comment entrer le japonais avec les malédictions Python
Comment utiliser le zip Python et énumérer
[Python] Comprendre comment utiliser les fonctions récursives
Résumé de l'utilisation de la liste Python
Comment utiliser les expressions régulières en Python
[Python2.7] Résumé de l'utilisation du sous-processus
Comment utiliser is et == en Python