How to use string as input for csv reader without storing it to file

故事扮演 提交于 2020-01-14 10:28:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!