【问题标题】:How to use string as input for csv reader without storing it to file如何使用字符串作为 csv 阅读器的输入而不将其存储到文件中
【发布时间】:2017-06-18 01:35:55
【问题描述】:

我正在尝试遍历 csv 文件中的行。我从 Web 位置获得 csv 文件为 string。当数据存储在文件中时,我知道如何使用with 创建csv.reader。我不知道的是,如何使用csv.reader 获取行而不将string 存储到文件中。我正在使用 Python 2.7.12。

我尝试过像这样创建StringIO 对象:

from StringIO import StringIO

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

但是,我收到了这个错误:

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__'

我知道StringIO 类没有__exit__ 方法,当when 完成对这个对象所做的任何事情时会调用该方法。

我的答案是如何正确地做到这一点?我想我可以通过继承 StringIO 类并添加 __exit__ 方法来改变它,但我怀疑有更简单的解决方案。

更新:

另外,我尝试了不同的组合:

with open(StringIO(csv_data)) as input_file:

with csv_data as input_file:

但是,当然,这些都不起作用。

【问题讨论】:

  • 只需使用 input_file = StringIO(csv_data) 代替 with 块。如何从网上下载 CSV 数据?下载时通常会得到一个文件对象,可以直接使用,而无需先将整个内容存储在一个字符串变量中,然后将该变量包装在StringIO中。
  • 无法在 Python 3.5 中重现。 StringIO 可用于with。 究竟您的版本和代码是什么? (from StringIO import StringIO 不好...)
  • @SvenMarnach 是的,我可以这样做,但我想使用with。我使用requests.get获取数据,然后从response.text创建csv_data。
  • @SvenMarnach:StringIO 支持上下文管理器接口,可以在with 语句中使用...
  • @SergeBallesta 对不起,忘了提。我使用 Python 2.7.12。我已经更新了这个问题。我使用完全 from StringIO import StringIO.

标签: python csv stringio


【解决方案1】:
>>> import csv
>>> csv_data = "some,string\nfor,example"
>>> result = csv.reader(csv_data.splitlines())
>>> list(result)
[['some', 'string'], ['for', 'example']]

【讨论】:

  • 如果字符串在引用值中有换行符,这将不起作用
【解决方案2】:

如果您喜欢上下文管理器,可以改用tempfile:

import tempfile


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

作为将字符串分割线直接传递给 csv 阅读器的一个优势,您可以写入任何大小的文件,然后在 csv 阅读器中安全地读取它,而不会出现内存问题。

此文件将自动关闭并删除

【讨论】:

    【解决方案3】:

    您应该使用 io 模块而不是 StringIO 模块,因为io.BytesIO 用于字节字符串或io.StringIO 用于 Unicode 都支持上下文管理器接口并且可以在with 语句中使用:

    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
    

    【讨论】:

    • 尝试此操作时出现以下错误:Traceback (most recent call last): File "scraper.py", line 227, in &lt;module&gt; with BytesIO(race_csv_data) as input_file: TypeError: 'unicode' does not have the buffer interface
    • @Fejs 这意味着您的 race_csv_data 是一个 unicode 字符串,您应该使用 io.StringIO 而不是 io.BytesIO (但您的示例使用了字节字符串 ;-) ...)跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多