Я пишу утилиту Python, которая должна анализировать большой, регулярно обновляемый CSV-файл, который я не контролирую. Утилита должна работать на сервере, на котором доступен только Python 2.4. CSV-файл вообще не заключает в кавычки значения полей, но версия библиотеки *1002* для Python 2.4 не дает мне никакого способа отключить кавычки, он просто позволяет установить символ кавычки (dialect.quotechar = '"'
или что угодно). Если я пытаюсь установить символ кавычки на None
или пустую строку, я получаю сообщение об ошибке.
Я могу обойти эту проблему, установив dialect.quotechar
для некоторого "редкого" символа, но это хрупко, поскольку нет символа ASCII, который я могу абсолютно гарантировать, не будет отображаться в значениях полей (кроме разделителя, но если я установлю dialect.quotechar = dialect.delimiter
, все пойдет предсказуемо).
В Python 2.5 и более поздних версиях , если я установлю dialect.quoting
на csv.QUOTE_NONE
, программа чтения CSV учитывает это и не интерпретирует любой символ как символ кавычки. Есть ли способ дублировать это поведение в Python 2.4?
ОБНОВЛЕНИЕ : Спасибо Триптиху и Марку Родди за помощь в сужении проблемы. Вот простейшая демонстрация:
>>> 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 строки есть один символ двойной кавычки. К сожалению, такая ситуация существует в моем наборе данных. Я принял решение Танджа: вручную назначить непечатаемый символ ("\x07"
или BEL
) в качестве кавычка. Это хакерство, но это работает, и я еще не видел другого решения, которое бы это сделало. Вот демонстрация решения в действии:
>>> 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
, а затем переопределяю значение кавычка, а не путем подкласса csv.Dialect
, но я не хочу, чтобы это отвлекало от реальной проблемы; две предыдущие сессии демонстрируют, что Sniffer
не проблема.)