Ich bin kein Profi und habe mir den Kopf zerkratzt, um zu verstehen, wofür genau StringIO verwendet wird. Ich habe mich im Internet nach Beispielen umgesehen. Fast alle Beispiele sind jedoch sehr abstrakt. Und sie zeigen nur, wie man es benutzt. Aber keiner von ihnen zeigt "warum" und "unter welchen Umständen" sollte / wird man es benutzen? Danke im Voraus
ps nicht zu verwechseln mit dieser Frage zum Stackoverflow: StringIO Verwendung, die String und StringIo vergleicht.
duck typing
Mit StringIO haben Sie dateiähnlichen Zugriff auf Zeichenfolgen, sodass Sie ein vorhandenes Modul verwenden können, das sich mit einer Datei befasst, fast nichts ändert und sie mit Zeichenfolgen arbeiten lässt.
Angenommen, Sie haben einen Logger, der Dinge in eine Datei schreibt, und möchten stattdessen die Protokollausgabe über das Netzwerk senden. Sie können die Datei lesen und ihren Inhalt in das Netzwerk schreiben, oder Sie können das Protokoll in ein StringIO-Objekt schreiben und an sein Netzwerkziel senden, ohne das Dateisystem zu berühren. StringIO macht es einfach, den ersten Weg zu gehen und dann zum zweiten Weg zu wechseln.
quelle
In Fällen, in denen Sie ein dateiähnliches Objekt möchten, das wie eine Datei ACTS-fähig ist, aber in einen speicherinternen Zeichenfolgenpuffer schreibt: StringIO ist das Tool. Wenn Sie große Zeichenfolgen erstellen, z. B. Nur-Text-Dokumente, und viele Zeichenfolgen verketten, ist es möglicherweise einfacher, nur StringIO anstelle einer Reihe
mystr += 'more stuff\n'
von Operationen zu verwenden.quelle
StringIO
, dass es erheblich schneller ist, wenn Sie mit mehreren Megabyte Zeichendaten im Vergleich zu Ausdrücken wiemystr += "more stuff\n"
innerhalb einer Schleife arbeiten, insbesondere wenn SiecStringIO.StringIO
statt nur verwenden könnenio.StringIO
.$ 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
cStringIO
existiert nicht einmal in Python 3. Es ist gut zu sehen, dass die naive Implementierung in 3.x gut optimiert ist!+=
wurde auch in Python 2 gut optimiert, AFAICT: Die+=
Version des obigen Benchmarks ist zehnmal so schnell wie StringIO und dreimal so schnell wie StringIO in Python2. (Auch in Ihrem Beitrag wird erwähntio.StringIO
; ist das nicht nur Python 3?)Einige Dinge, für die ich es persönlich verwendet habe:
Caching ganzer Dateien. Ich habe ein Skript, das PDFs liest und verschiedene Dinge überprüft. Die von mir verwendete PDF-Bibliothek nimmt eine geöffnete Datei in ihren Dokumentkonstruktor. Ich habe ursprünglich nur das PDF geöffnet, das ich lesen wollte. Als ich es jedoch so änderte, dass die gesamte Datei auf einmal in den Speicher gelesen und dann ein StringIO-Objekt an die PDF-Bibliothek übergeben wurde, wurde die Laufzeit meines Skripts halbiert.
Aufgeschobenes Drucken. Das gleiche Skript druckt vor jedem gelesenen PDF einen Header. Ich kann jedoch in der Befehlszeile angeben, ob bestimmte Tests in der Konfigurationsdatei ignoriert oder nur bestimmte eingeschlossen werden sollen. Wenn ich alle Tests für eine bestimmte PDF-Datei ignoriere, möchte ich nicht, dass der Header gedruckt wird, aber ich weiß nicht, wie viele Tests ich ausgeführt habe, bis ich die Tests ausgeführt habe (die Tests können auch dynamisch definiert werden). Also erfasse ich den Header in einem StringIO-Objekt, indem
sys.stdout
ich ihn verweise und jedes Mal, wenn ich einen Test durchführe, überprüfe ich, ob dieses Objekt etwas enthält. Wenn ja, drucke ich es dann aus und setze es auf leer zurück. Voila, nur PDFs mit Tests haben Header gedruckt.quelle
Ich habe StringIO gerade in der Praxis für zwei Dinge verwendet:
print
Arbeit leistet , durch Umleitensys.stdout
zu einerStringIO
Instanz zur einfachen Analyse;ElementTree
und anschließendwrite
zum Senden über eine HTTP-Verbindung.Nicht, dass du es
StringIO
oft brauchst , aber manchmal ist es ziemlich nützlich.quelle
Ich habe es anstelle von Textdateien für Unit-Tests verwendet.
Zum Beispiel, um eine CSV-Datei zum Testen mit Pandas (Python 3) zu erstellen:
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
Aus der Dokumentation hier :
quelle
Django hat eine Funktion, mit
call_command
der Verwaltungsbefehle aufgerufen werden. Diese Funktion druckt die Ausgabe an stdout und gibt keinen Wert zurück. Wenn Sie wissen möchten, ob der Befehl erfolgreich ausgeführt wurde oder nicht, müssen Sie die Ausgabe prüfen und entscheiden.Mit StringIO können Sie die Ausgabe erfassen und prüfen, ob die gewünschte Ausgabe gewünscht wird oder nicht.
with io.StringIO() as output: call_command('custom_command', stdout=output) if 'Success' not in output.getvalue(): print('Custom command failed...')
quelle