2017-02-01 4 views
1

Ich versuche, Zeilen in einer csv Datei durchlaufen. Ich bekomme csv Datei als string von einem Web-Speicherort. Ich kann csv.reader mit with erstellen, wenn Daten in einer Datei gespeichert werden. Was ich nicht weiß, ist, wie man Zeilen mit csv.reader erhält, ohne string in einer Datei zu speichern. Ich benutze Python 2.7.12.So verwenden Sie Zeichenfolge als Eingabe für CSV-Reader, ohne es in Datei zu speichern

Ich habe versucht StringIO Objekt wie folgt zu erstellen:

from StringIO import StringIO 

csv_data = "some_string\nfor_example" 
with StringIO(csv_data) as input_file: 
    csv_reader = reader(csv_data, delimiter=",", quotechar='"') 

Allerdings bin ich immer diese Fehlermeldung:

Traceback (most recent call last): 
    File "scraper.py", line 228, in <module> 
    with StringIO(csv_data) as input_file: 
AttributeError: StringIO instance has no attribute '__exit__' 

Ich verstehe, dass StringIO Klasse nicht __exit__ Methode hat die wird aufgerufen, wenn when beendet wird, was auch immer es mit diesem Objekt macht.

Meine Antwort ist, wie man das richtig macht? Ich nehme an, ich kann StringIO Klasse durch Unterklassenbildung und __exit__ Methode ändern, aber ich vermute, dass es eine einfachere Lösung gibt.

Update:

Auch ich habe versucht, verschiedene Kombinationen, die mir in den Sinn kam:

with open(StringIO(csv_data)) as input_file: 

with csv_data as input_file: 

aber natürlich, keiner von denen gearbeitet.

+2

Verwenden Sie einfach 'input_file = StringIO (csv_data)' anstelle von 'mit' Block. Wie laden Sie die CSV-Daten aus dem Internet herunter? Normalerweise erhalten Sie beim Herunterladen ein Dateiobjekt, das direkt verwendet werden kann, ohne zuerst den gesamten Inhalt in einer String-Variablen zu speichern und dann diese Variable in 'StringIO' zu verpacken. –

+0

Kann in Python 3.5 nicht reproduziert werden. 'StringIO' kann in einem' mit' verwendet werden. Was ist * genau * deine Version und der Code? ('von StringIO importieren StringIO' ist * schlecht * ...) –

+0

@SvenMarnach Ja, ich kann es so machen, aber ich würde' mit' verwenden. Ich verwende 'requests.get', um Daten zu erhalten, und erstelle' csv_data' aus 'response.text'. – Fejs

Antwort

3
>>> import csv 
>>> csv_data = "some,string\nfor,example" 
>>> result = csv.reader(csv_data.splitlines()) 
>>> list(result) 
[['some', 'string'], ['for', 'example']] 
+0

Das ist eine ganz nette Lösung, danke. – Fejs

+0

Das wird nicht funktionieren, wenn die Zeichenfolge Zeilenumbrüche innerhalb des angegebenen Wertes – swooby

0

Wenn Sie Kontext-Manager möchten, können Sie tempfile statt:

import tempfile 


with tempfile.NamedTemporaryFile(mode='w') as t: 
    t.write('csv_data') 
    t.seek(0) 
    csv_reader = reader(open(t.name), delimiter=",", quotechar='"') 

Als Vorteil Zeichenfolge Teilungslinien direkt an csv Leser weitergeben Sie Datei jeder Größe schreiben und dann lesen Sie es sicher in CSV-Reader ohne Speicherprobleme.

Diese Datei wird automatisch

1

geschlossen und gelöscht werden Sie sollten den IO-Modul anstelle des StringIO ein, weil io.BytesIO für Byte-String oder io.StringIO für Unicode diejenigen verwenden, um sowohl die Kontext-Manager-Schnittstelle unterstützen und kann in with verwendet werden Anweisungen:

from io import BytesIO 
from csv import reader 
csv_data = "some_string\nfor_example" 
with BytesIO(csv_data) as input_file: 
    csv_reader = reader(input_file, delimiter=",", quotechar='"') 
    for row in csv_reader: 
     print row 
+0

hat erhalte ich folgende Fehlermeldung, wenn ich versuche dies: 'Traceback (jüngste Aufforderung zuletzt): File„scraper.py“, Linie 227, in mit BytesIO (race_csv_data) als Eingabedatei: TypeError: 'Unicode' hat nicht die Pufferschnittstelle' – Fejs

+0

@Fejs Das bedeutet, dass Ihre 'race_csv_data' eine Unicode-Zeichenkette ist und Sie' io.StringIO' anstelle von 'io.BytesIO verwenden sollten '(aber Ihr Beispiel hat eine Byte-Zeichenfolge verwendet ;-) ...) –

Verwandte Themen