Почему вкладки написаны \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
,