【问题标题】:How can I disable quoting in the Python 2.4 CSV reader?如何在 Python 2.4 CSV 阅读器中禁用引用?
【发布时间】:2010-10-04 09:21:23
【问题描述】:

我正在编写一个 Python 实用程序,它需要解析一个我无法控制的、定期更新的大型 CSV 文件。该实用程序必须在只有 Python 2.4 可用的服务器上运行。 CSV 文件根本不引用字段值,但 Python 2.4 version of the csv library 似乎没有给我任何关闭引用的方法,它只允许我设置引号字符(dialect.quotechar = '"' 或其他)。如果我尝试将引号字符设置为 None 或空字符串,则会出现错误。

我可以通过将dialect.quotechar 设置为一些“稀有”字符来解决这个问题,但这很脆弱,因为没有 ASCII 字符我可以绝对保证不会出现在字段值中(分隔符除外,但是如果我设置dialect.quotechar = dialect.delimiter,事情就会出乎意料地变得混乱)。

Python 2.5 and later 中,如果我将dialect.quoting 设置为csv.QUOTE_NONE,CSV 阅读器会尊重这一点并且不会将任何字符解释为引号字符。有没有办法在 Python 2.4 中复制这种行为?

更新:感谢 Triptych 和 Mark Roddy 帮助缩小问题范围。这是一个最简单的演示:

>>> import csv
>>> import StringIO
>>> data = """
... 1,2,3,4,"5
... 1,2,3,4,5
... """
>>> reader = csv.reader(StringIO.StringIO(data))
>>> for i in reader: print i
... 
[]
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
_csv.Error: newline inside string

仅当行的 final 列中有单个双引号字符时才会出现此问题。不幸的是,这种情况存在于我的数据集中。我接受了 Tanj 的解决方案:手动分配一个非打印字符("\x07"BEL)作为引号字符。这很hacky,但它有效,而且我还没有看到另一个解决方案。以下是实际解决方案的演示:

>>> import csv
>>> import StringIO
>>> class MyDialect(csv.Dialect):
...     quotechar = '\x07'
...     delimiter = ','
...     lineterminator = '\n'
...     doublequote = False
...     skipinitialspace = False
...     quoting = csv.QUOTE_NONE
...     escapechar = '\\'
... 
>>> dialect = MyDialect()
>>> data = """
... 1,2,3,4,"5
... 1,2,3,4,5
... """
>>> reader = csv.reader(StringIO.StringIO(data), dialect=dialect)
>>> for i in reader: print i
... 
[]
['1', '2', '3', '4', '"5']
['1', '2', '3', '4', '5']

在 Python 2.5+ 中,将引用设置为 csv.QUOTE_NONE 就足够了,而 quotechar 的值将无关紧要。 (我实际上是通过csv.Sniffer 获取我的初始方言,然后覆盖quotechar 值,而不是通过子类化csv.Dialect,但我不希望这会分散真正问题的注意力;以上两个会话表明Sniffer 不是问题。)

【问题讨论】:

    标签: python csv


    【解决方案1】:

    我不知道 python 是否愿意/允许它,但您可以使用不可打印的 ascii 代码,例如 BEL 或 BS(退格)这些我认为非常罕见。

    【讨论】:

    • 哇,好主意。设置 csv.quotechar = '\x07' (BEL) 似乎可以解决问题。无法想象他们是如何将其纳入 CSV 数据的。
    • 所以,您也可以将 quotechar 设置为 ''(空字符串)。至少,这适用于 python 2.7 ...不确定以前的版本,所以它可能不适用。
    • @underrun 我在问题中提到将quotechar 设置为None 或空字符串失败(在Python 2.4 中)。
    【解决方案2】:

    我尝试了几个使用 Python 2.4.3 的示例,它似乎足够聪明,可以检测到字段没有被引用。

    我知道您已经接受了一个(有点老套)的答案,但是您是否尝试过只保留 reader.dialect.quotechar 值?如果这样做会怎样?

    我们有没有机会获得示例输入?

    【讨论】:

    • 我仍然对一种不那么老套的方法感兴趣,如果有的话。我可以很快上传一些示例输入。我使用的方言是由 csv.Sniffer 对象生成的(我需要对格式更改尽可能健壮)。如果我不考虑quotechar,它似乎默认为双引号'"'。
    【解决方案3】:

    为三联画+1

    确认 csv.reader 自动处理不带引号的 csv 文件:

    >>> import StringIO
    >>> import csv
    >>> data="""
    ... 1,2,3,4,5
    ... 1,2,3,4,5
    ... 1,2,3,4,5
    ... """
    >>> reader=csv.reader(StringIO.StringIO(data))
    >>> for i in reader:
    ...     print i
    ... 
    []
    ['1', '2', '3', '4', '5']
    ['1', '2', '3', '4', '5']
    ['1', '2', '3', '4', '5']
    

    【讨论】:

    • 这并不是一个真正的相关测试,因为无论 quotechar 设置什么,引用都是可选的;它可以很好地处理未引用的字段。问题是quotechar何时出现在数据中;显然,只有当它出现在最后一列时。感谢您推动我缩小范围。
    猜你喜欢
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 2018-06-05
    • 1970-01-01
    相关资源
    最近更新 更多