web-dev-qa-db-fra.com

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

Je ne suis pas un professionnel et je me suis efforcé de comprendre à quoi sert exactement StringIO. J'ai cherché des exemples sur Internet. Cependant, presque tous les exemples sont très abstraits. Et ils montrent juste "comment" l'utiliser. Mais aucun d’entre eux n’indique "pourquoi" et "dans quelles circonstances" on devrait/on va l’utiliser?

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

61
Hossein

Il est utilisé lorsque certaines API n'utilisent que des fichiers, mais que vous devez utiliser une chaîne. Par exemple, pour compresser une chaîne en utilisant le module 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()
77
Petr Viktorin

StringIO vous donne un accès similaire à un fichier aux chaînes, vous pouvez donc utiliser un module existant qui traite un fichier, ne changez presque rien et le fait fonctionner avec des chaînes.

Par exemple, disons que vous avez un enregistreur qui écrit des choses dans un fichier et que vous souhaitez plutôt envoyer la sortie du journal sur le réseau. Vous pouvez lire le fichier et écrire son contenu sur le réseau. Vous pouvez également écrire le journal dans un objet StringIO et l'envoyer à sa destination réseau sans toucher au système de fichiers. StringIO facilite la procédure du premier moyen, puis passe à la deuxième.

28
nmichaels

Dans les cas où vous souhaitez un objet de type fichier qui agit comme un fichier, mais écrit dans un tampon de chaîne en mémoire: StringIO est l'outil. Si vous créez des chaînes de grande taille, telles que des documents en texte brut, et effectuez beaucoup de concaténation de chaînes, il vous sera peut-être plus facile d'utiliser simplement StringIO au lieu d'un tas d'opérations de type mystr += 'more stuff\n'.

15
jathanism

Je viens d'utiliser StringIO dans la pratique pour deux choses:

  • Pour tester par unité un script qui effectue beaucoup de printing, en redirigeant sys.stdout vers une instance StringIO pour une analyse facile;
  • Pour créer un document XML bien formé garanti (une requête d'API personnalisée) à l'aide de ElementTree, puis write, pour l'envoi via une connexion HTTP.

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

9
9000

Quelques choses pour lesquelles je l'ai personnellement utilisé:

  1. Mise en cache de fichiers entiers. J'ai un script qui lit les PDF et valide diverses choses à leur sujet. La bibliothèque PDF que j'utilise prend un fichier ouvert dans son constructeur de document. À l'origine, je venais d'ouvrir le fichier PDF qui m'intéressait, mais lorsque je l'ai modifié pour lire le fichier entier en une fois en mémoire, puis passer un objet StringIO à la bibliothèque PDF, la durée d'exécution de mon script a été coupé en deux.

  2. Impression différée. Le même script imprime un en-tête avant chaque lecture de PDF. Cependant, je peux spécifier sur la ligne de commande s'il faut ignorer certains tests contenus dans son fichier de configuration ou n'en inclure que certains. Si j'ignore tous tests 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és avant d'avoir terminé les tests (les tests peuvent être défini dynamiquement également). Donc, je capture l'en-tête dans un objet StringIO en changeant sys.stdout pour qu'il y pointe, et chaque fois que je lance un test, je vérifie si cet objet contient quoi que ce soit. Si c'est le cas, je l'imprime alors et le réinitialise à vide. Voila, seuls les PDFs ayant des tests ont des en-têtes imprimés.

8
kindall

Je l'ai utilisé à la place des fichiers texte pour les tests unitaires. 

Par exemple, pour créer un 'fichier' csv à tester avec des pandas (Python 3):

import io
f = io.StringIO("id,name\n1,brian\n2,amanda\n3,zoey\n")
df = pd.read_csv(f) # pandas takes a file path or a file-like object

De la documentation ici :

Flux en mémoire pour les E/S de texte. Le tampon de texte est supprimé lorsque la méthode close () est appelée.

La valeur initiale du tampon peut être définie en fournissant initial_value.

method getvalue (): Retourne une chaîne contenant le contenu entier du tampon. 

0
Brian Burns

Django a une fonction call_command qui est utilisée pour appeler des commandes de gestion. Cette fonction imprime la sortie sur stdout et ne renvoie aucune valeur. Si vous voulez savoir si la commande a été exécutée avec succès ou non, vous devez examiner le résultat et décider.

En utilisant StringIO, vous pouvez capturer la sortie et vérifier si elle est désirée ou non.

with io.StringIO() as output:
    call_command('custom_command', stdout=output)
    if 'Success' not in output.getvalue():
        print('Custom command failed...')
0
ChillarAnand