Подтвердить что ты не робот

Как отключить цитирование в Python 2.4 CSV-ридере?

Я пишу утилиту Python, которая должна анализировать большой, регулярно обновляемый CSV файл, который я не контролирую. Утилита должна запускаться на сервере с доступным только Python 2.4. Файл CSV вообще не указывает значения полей, но версия библиотеки csv версии 2.4 для Python не кажется мне каким-либо образом off quoting, он просто позволяет мне задать символ кавычки (dialect.quotechar = '"' или что-то еще). Если я попытаюсь установить символ кавычки на None или пустую строку, я получаю сообщение об ошибке.

Я могу обойти это, установив dialect.quotechar на некоторый "редкий" символ, но это хрупкое, так как нет символа ASCII, который я могу абсолютно гарантировать, не будет отображаться в значениях поля (кроме разделителя, но если я устанавливаю dialect.quotechar = dialect.delimiter, вещи идут предсказуемо haywire).

В 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

Проблема возникает только при наличии в последнем столбце строки одного символа двойной кавычки. К сожалению, эта ситуация существует в моем наборе данных. Я принял решение Tanj: вручную назначить непечатаемый символ ("\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 не проблема.)

4b9b3361

Ответ 1

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

Ответ 2

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

Я знаю, что вы уже приняли (слегка взломанный) ответ, но попробовали ли вы оставить только значение reader.dialect.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']