87 votes

A quoi sert StringIO en python dans la réalité ?

Je ne suis pas un pro et j'ai du mal à comprendre à quoi sert exactement StringIO. J'ai cherché des exemples sur Internet. Cependant, presque tous les exemples sont très abstraits. Ils montrent juste "comment" l'utiliser. Mais aucun d'entre eux ne montre "pourquoi" et "dans quelles circonstances" on doit/on va l'utiliser ? Merci d'avance

p.s. à ne pas confondre avec cette question sur stackoverflow : Utilisation de StringIO qui compare string et StringIo.

101voto

Petr Viktorin Points 13687

Il est utilisé lorsque vous avez une API qui ne prend que des fichiers, mais que vous devez utiliser une chaîne. Par exemple, pour compresser une chaîne de caractères à l'aide de la fonction gzip dans Python 2 :

import gzip
import StringIO

stringio = StringIO.StringIO()
gzip_file = gzip.GzipFile(fileobj=stringio, mode='w')
gzip_file.write('Hello World')
gzip_file.close()

stringio.getvalue()

3 votes

En d'autres termes : duck typing :D

2 votes

Depuis Python 3.2, le module gzip dispose de fonctions permettant de compresser directement les données. (Mais toute bibliothèque open-source bien connue qui a actuellement besoin de StringIO développera probablement de telles fonctions après un certain temps, donc plutôt que de chercher un nouvel exemple, je laisserai gzip ici).

41voto

nmichaels Points 21955

StringIO vous donne un accès de type fichier aux chaînes de caractères, donc vous pouvez utiliser un module existant qui traite un fichier et ne changer presque rien pour le faire fonctionner avec des chaînes de caractères.

Par exemple, disons que vous avez un enregistreur qui écrit des choses dans un fichier et que vous voulez plutôt envoyer la sortie du journal sur le réseau. Vous pouvez lire le fichier et écrire son contenu sur le réseau, ou vous pouvez écrire le journal dans un objet StringIO et l'expédier vers sa destination réseau sans toucher au système de fichiers. StringIO permet de faire facilement la première méthode puis de passer à la seconde.

2 votes

StringIO est également utile pour écrire un fichier directement dans S3 (c'est-à-dire sans avoir besoin de l'enregistrer localement puis de le télécharger).

20voto

jathanism Points 15208

Dans les cas où vous voulez un objet de type fichier qui se comporte comme un fichier, mais qui écrit dans un tampon de chaîne en mémoire : StringIO est l'outil qu'il vous faut. Si vous construisez de grandes chaînes de caractères, comme des documents en texte brut, et que vous faites beaucoup de concaténation de chaînes de caractères, vous pouvez trouver plus facile d'utiliser StringIO au lieu d'un tas d'objets de type mystr += 'more stuff\n' le type d'opérations.

3 votes

J'ai aussi trouvé StringIO est considérablement plus rapide si vous traitez plusieurs mégaoctets de données de caractères, par rapport à des expressions telles que mystr += "more stuff\n" dans une boucle, surtout si vous pouvez utiliser cStringIO.StringIO au lieu de simplement io.StringIO .

1 votes

@SeldomNeedy L'avez-vous évalué ? C'était peut-être vrai en 2016, mais la concaténation de chaînes de caractères avec += est plutôt optimisée de nos jours (elle utilise le compteur de référence pour muter la chaîne de caractères en place lorsque cela est sûr). Benchmark : $ python3 -m timeit -s "from io import StringIO; line = 'a'*80" $'s = StringIO()\nfor i in range(10000): s.write(line)\ns = s.getvalue()' 500 loops, best of 5: 599 usec per loop ; python3 -m timeit -s "line = 'a'*80" $'s = ""\nfor i in range(10000): s += line' 500 loops, best of 5: 588 usec per loop

0 votes

@Clément Je faisais référence à Python 2.x ; cStringIO n'existe même pas dans Python 3. Il est bon de voir que l'implémentation naïve est bien optimisée en 3.x !

10voto

kindall Points 60645

J'ai personnellement utilisé ce produit pour plusieurs choses :

  1. Mise en cache de fichiers entiers. J'ai un script qui lit les PDFs et fait la validation de diverses choses à leur sujet. La bibliothèque PDF que j'utilise prend un fichier ouvert dans son constructeur de document. À l'origine, je n'ouvrais que le PDF qui m'intéressait, mais lorsque je l'ai modifié pour lire le fichier entier en une seule fois en mémoire puis passer un objet StringIO à la bibliothèque PDF, le temps d'exécution de mon script a été réduit de moitié.

  2. Impression différée. Le même script imprime un en-tête avant chaque PDF qu'il lit. Cependant, je peux spécifier sur la ligne de commande s'il faut ignorer certains tests qui se trouvent dans son fichier de configuration, ou n'en inclure que certains. Si j'ignore tous pour un PDF donné, je ne veux pas que l'en-tête soit imprimé, mais je ne saurai pas combien de tests j'ai exécuté avant d'avoir terminé les tests (les tests peuvent également être définis dynamiquement). Donc je capture l'en-tête dans un objet StringIO en changeant sys.stdout pour le désigner, et chaque fois que je lance un test, je vérifie si cet objet contient quelque chose. Si c'est le cas, je l'imprime alors et je le réinitialise à vide. Voilà, seuls les PDF qui ont fait l'objet de tests ont des en-têtes imprimés.

9voto

9000 Points 13242

Je viens d'utiliser StringIO en pratique pour deux choses :

  • Pour tester en unité un script qui fait beaucoup de print en redirigeant sys.stdout à un StringIO pour faciliter l'analyse ;
  • Pour créer un document XML garanti bien formé (une demande d'API personnalisée) en utilisant ElementTree et ensuite write pour l'envoyer via une connexion HTTP.

Pas que vous ayez besoin StringIO souvent mais parfois, c'est très utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X