Maison >développement back-end >Tutoriel Python >Travailler avec des fichiers de manière asynchrone en Python à l'aide d'aiofiles et d'asyncio

Travailler avec des fichiers de manière asynchrone en Python à l'aide d'aiofiles et d'asyncio

DDD
DDDoriginal
2025-01-15 09:52:44782parcourir

Le code asynchrone est devenu un pilier du développement Python. Avec l'arrivée d'asyncio dans la bibliothèque standard et de nombreux packages tiers fournissant des fonctionnalités compatibles avec celui-ci, ce paradigme ne disparaîtra pas de sitôt.

Si vous écrivez du code asynchrone, il est important de vous assurer que toutes les parties de votre code fonctionnent ensemble afin qu'un aspect de celui-ci ne ralentisse pas tout le reste. Les E/S de fichiers peuvent être un bloqueur courant sur ce front, voyons donc comment utiliser la bibliothèque aiofiles pour travailler avec des fichiers de manière asynchrone.

En commençant par les bases, voici tout le code dont vous avez besoin pour lire le contenu d'un fichier de manière asynchrone (au sein d'une fonction asynchrone) :

async with aiofiles.open('filename', mode='r') as f:
    contents = await f.read()
print(contents)

Avançons et creusons plus profondément.

Qu'est-ce que le code non bloquant ?

Vous pouvez entendre des termes comme « asynchrone », « non bloquant » ou « simultané » et être un peu confus quant à leur signification. Selon ce tutoriel beaucoup plus détaillé, deux des propriétés principales sont :

  • Les routines asynchrones sont capables de « faire une pause » en attendant leur résultat final pour laisser d'autres routines s'exécuter entre-temps.
  • Le code asynchrone, grâce au mécanisme ci-dessus, facilite l'exécution simultanée. Pour le dire autrement, le code asynchrone donne l’apparence de la concurrence.

Le code asynchrone est donc un code qui peut se bloquer en attendant un résultat, afin de laisser d'autres codes s'exécuter entre-temps. Il ne « bloque » pas l'exécution d'autres codes, nous pouvons donc l'appeler code « non bloquant ».

La bibliothèque asyncio fournit une variété d'outils aux développeurs Python pour ce faire, et aiofiles fournit des fonctionnalités encore plus spécifiques pour travailler avec des fichiers.

Configuration

Assurez-vous d'avoir configuré votre environnement Python avant de commencer. Suivez ce guide jusqu'à la section virtualenv si vous avez besoin d'aide. Faire en sorte que tout fonctionne correctement, notamment en ce qui concerne les environnements virtuels, est important pour isoler vos dépendances si vous avez plusieurs projets en cours d'exécution sur la même machine. Vous aurez besoin d'au moins Python 3.7 ou supérieur pour exécuter le code de cet article.

Maintenant que votre environnement est configuré, vous allez devoir installer des bibliothèques tierces. Nous allons utiliser des aiofiles alors installez-le avec la commande suivante après avoir activé votre environnement virtuel :

pip install aiofiles==0.6.0

Pour les exemples du reste de cet article, nous utiliserons des fichiers JSON de données API Pokémon correspondant aux 150 Pokémon d'origine. Vous pouvez télécharger un dossier avec tous ces éléments ici. Avec cela, vous devriez être prêt à passer à autre chose et à écrire du code.

Lecture à partir d'un fichier avec aiofiles

Commençons par simplement ouvrir un fichier correspondant à un Pokémon particulier, analyser son JSON dans un dictionnaire et imprimer son nom :

async with aiofiles.open('filename', mode='r') as f:
    contents = await f.read()
print(contents)

Lors de l'exécution de ce code, vous devriez voir « articuno » imprimé sur le terminal. Vous pouvez également parcourir le fichier de manière asynchrone, ligne par ligne (ce code imprimera les 9271 lignes d'articuno.json) :

pip install aiofiles==0.6.0

Écrire dans un fichier avec des fichiers aiofiles

L'écriture dans un fichier est également similaire aux E/S de fichier Python standard. Disons que nous voulions créer des fichiers contenant une liste de tous les mouvements que chaque Pokémon peut apprendre. Pour un exemple simple, voici ce que nous ferions pour le Pokémon Idem, qui ne peut apprendre que le mouvement "transformation" :

import aiofiles
import asyncio
import json


async def main():
    async with aiofiles.open('articuno.json', mode='r') as f:
        contents = await f.read()
    pokemon = json.loads(contents)
    print(pokemon['name'])

asyncio.run(main())

Essayons ceci avec un Pokémon qui a plus d'un mouvement, comme Rhydon :

import aiofiles
import asyncio

async def main():
    async with aiofiles.open('articuno.json', mode='r') as f:
        async for line in f:
            print(line)

asyncio.run(main())

Si vous ouvrez rhydon_moves.txt, vous devriez voir un fichier de 112 lignes qui commence par quelque chose comme ceci.

A screenshot of the rhydon_moves.txt file

Utiliser asyncio pour parcourir de nombreux fichiers de manière asynchrone

Maintenant, soyons un peu plus compliqués et faisons cela pour les 150 Pokémon pour lesquels nous avons des fichiers JSON. Notre code devra lire chaque fichier, analyser le JSON et réécrire les mouvements de chaque Pokémon dans un nouveau fichier :

import aiofiles
import asyncio

async def main():
    async with aiofiles.open('ditto_moves.txt', mode='w') as f:
        await f.write('transform')

asyncio.run(main())

Après avoir exécuté ce code, vous devriez voir le répertoire des fichiers Pokémon rempli de fichiers .txt à côté de ceux .json, contenant des listes de mouvements correspondant à chaque Pokémon.

A screenshot of the files in the directory

Si vous devez effectuer des actions asynchrones et souhaitez terminer avec des données correspondant à ces tâches asynchrones, comme une liste des mouvements de chaque Pokémon après avoir écrit les fichiers, vous pouvez utiliser asyncio.ensure_future et asyncio.gather.

Vous pouvez diviser la partie de votre code qui gère chaque fichier dans sa propre fonction asynchrone et ajouter des promesses pour ces appels de fonction à une liste de tâches. Voici un exemple de ce à quoi ressembleraient cette fonction et votre nouvelle fonction principale :

import aiofiles
import asyncio
import json


async def main():
    # Read the contents of the json file.
    async with aiofiles.open('rhydon.json', mode='r') as f:
        contents = await f.read()

    # Load it into a dictionary and create a list of moves.
    pokemon = json.loads(contents)
    name = pokemon['name']
    moves = [move['move']['name'] for move in pokemon['moves']]

    # Open a new file to write the list of moves into.
    async with aiofiles.open(f'{name}_moves.txt', mode='w') as f:
        await f.write('\n'.join(moves))


asyncio.run(main())

Il s'agit d'une manière courante d'utiliser du code asynchrone en Python, et elle est souvent utilisée pour des choses comme faire des requêtes HTTP.

Alors à quoi ça sert ?

Les exemples de cet article utilisant les données du Pokémon n'étaient qu'une excuse pour montrer la fonctionnalité du module aiofiles et comment vous écririez du code pour naviguer dans un répertoire de fichiers en lecture et en écriture. J'espère que vous pourrez adapter ces exemples de code aux problèmes spécifiques que vous essayez de résoudre afin que les E/S de fichiers ne deviennent pas un bloqueur dans votre code asynchrone.

Nous n'avons fait qu'effleurer la surface de ce que vous pouvez faire avec aiohttp et asyncio, mais j'espère que cela a facilité un peu votre voyage dans le monde de Python asynchrone.

J'ai hâte de voir ce que vous construisez. N'hésitez pas à nous contacter et à partager vos expériences ou à poser des questions.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn