Как я могу отключить цитирование в читателе Python 2.4 CSV? - PullRequest
10 голосов
/ 30 января 2009

Я пишу утилиту 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 не проблема.)

Ответы [ 3 ]

13 голосов
/ 30 января 2009

Я не знаю, хотел бы / разрешил ли он Python, но не могли бы вы использовать непечатаемый код ascii, такой как BEL или BS (backspace)?

3 голосов
/ 30 января 2009

Я попробовал несколько примеров использования Python 2.4.3, и он оказался достаточно умным, чтобы обнаружить, что поля не были заключены в кавычки.

Я знаю, что вы уже приняли (немного хакерский) ответ, но пытались ли вы просто оставить значение reader.dialect.quotechar в покое? Что произойдет, если вы это сделаете?

Есть ли шанс, что мы могли бы получить пример ввода?

0 голосов
/ 30 января 2009

+ 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']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...