问题
I'm trying to loop through rows in a csv
file. I get csv
file as string
from a web location. I know how to create csv.reader
using with
when data is stored in a file. What I don't know is, how to get rows using csv.reader
without storing string
to a file. I'm using Python 2.7.12.
I've tried to create StringIO
object like this:
from StringIO import StringIO
csv_data = "some_string\nfor_example"
with StringIO(csv_data) as input_file:
csv_reader = reader(csv_data, delimiter=",", quotechar='"')
However, I'm getting this error:
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__'
I understand that StringIO
class doesn't have __exit__
method which is called when when
finishes doing whatever it does with this object.
My answer is how to do this correctly? I suppose I can alter StringIO
class by subclassing it and adding __exit__
method, but I suspect that there is easier solution.
Update:
Also, I've tried different combinations that came to my mind:
with open(StringIO(csv_data)) as input_file:
with csv_data as input_file:
but, of course, none of those worked.
回答1:
>>> import csv
>>> csv_data = "some,string\nfor,example"
>>> result = csv.reader(csv_data.splitlines())
>>> list(result)
[['some', 'string'], ['for', 'example']]
回答2:
If you like context managers, you can use tempfile
instead:
import tempfile
with tempfile.NamedTemporaryFile(mode='w') as t:
t.write('csv_data')
t.seek(0)
csv_reader = reader(open(t.name), delimiter=",", quotechar='"')
As an advantage to pass string splitlines directly to csv reader you can write file of any size and then safely read it in csv reader without memory issues.
This file will be closed and deleted automatically
回答3:
You should use the io module instead of the StringIO one, because io.BytesIO
for byte string or io.StringIO
for Unicode ones both support the context manager interface and can be used in with
statements:
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
来源:https://stackoverflow.com/questions/41977519/how-to-use-string-as-input-for-csv-reader-without-storing-it-to-file