Почему вкладки написаны \t в CSV-файле с использованием Python

Допустим, у меня список списка содержит вкладки персонажа:

mylist = [['line 1', '<a href="//<% serverNames[0].getHostname() %>:'],
          ['line 2', '     <% master.getConfiguration()>']]

Когда я сохраняю список в CSV файл, tab в коде в строке 2 будет написано \t,

line | code
-----------------------------------------------------
   1 | <a href="//<% serverNames[0].getHostname() %>:
   2 | \t   <% master.getConfiguration()>

Мне нужно это как есть, потому что я хочу сравнить код с другими списками. Поэтому я не хочу заменять вкладку другими символами, например пробелами.

Код, который я написал:

with open('codelist.csv', 'w') as file:
   header = ['line','code']
   writers = csv.writer(file)
   writers.writerow(header)
   for row in mylist:
      writers.writerow(row)

Как решить эту проблему?

1 ответ

Решение

Я не могу воспроизвести точную ошибку в Python2 или Python3, но у меня есть предположение о том, что может происходить.

Согласно документации для csv.writer находится здесь,

Все другие нестроковые данные перед записью преобразуются в str().

Обратите внимание на то, что питон str Функция точно описывает поведение, которое вы описываете, если вы предоставляете строку, содержащую фактический символ табуляции:

 >>> str('  ')
 '\t'

Конечно, у вас есть строковые данные, но приведенная выше документация не говорит, что в действительности означает другое. Вот что я нашел в реализации writerows в _csv.c, расположенный здесь:

    if (PyUnicode_Check(field)) {
        append_ok = join_append(self, field, quoted);
        Py_DECREF(field);
    }
    else if (field == Py_None) {
        append_ok = join_append(self, NULL, quoted);
        Py_DECREF(field);
    }
    else {
        PyObject *str;

        str = PyObject_Str(field);
        Py_DECREF(field);
        if (str == NULL) {
            Py_DECREF(iter);
            return NULL;
        }
        append_ok = join_append(self, str, quoted);
        Py_DECREF(str);
    }

Поэтому я подозреваю, что здесь происходит то, что каким-то образом ваш список содержит строковые данные в формате, который не распознается как строка в кодировке Юникод, и который, следовательно, не соответствует PyUnicode_Check ветка в тесте, отправляется через str (упоминается как PyObject_Str в коде C), и, следовательно, получает встроенную escape-последовательность.

Поэтому вы можете проверить, как эти данные попадают в ваши списки.

В качестве альтернативы, возможно, источник, на который я смотрю, не соответствует используемой вами версии Python, и вы используете версию, которая, скажем, просто запускает все str,

Другие вопросы по тегам