Как записать UTF-8 в файл CSV

84

Я пытаюсь создать текстовый файл в формате csv из PyQt4 QTableWidget. Я хочу написать текст в кодировке UTF-8, потому что он содержит специальные символы. Я использую следующий код:

import codecs
...
myfile = codecs.open(filename, 'w','utf-8')
...
f = result.table.item(i,c).text()
myfile.write(f+";")

Это работает до тех пор, пока в ячейке не будет специального символа. Я пробовал также с

myfile = open(filename, 'w')
...
f = unicode(result.table.item(i,c).text(), "utf-8")

Но он также останавливается, когда появляется специальный символ. Понятия не имею, что делаю не так.

Мартин
источник
"это сальсо топы"? Что это значит? Какая у вас ошибка? Каков ваш вклад?
Входными данными является pyqt4 QTableWidgetItem. Проблема в том, что я не получаю никаких ошибок, потому что скрипт работает как плагин.
Мартин
Затем попробуйте воспроизвести проблему за пределами QT.
Нашел решение. Я должен был написатьmyfile.write(u"%s"&f+";")
Мартин

Ответы:

106

Из вашей оболочки запустите:

pip2 install unicodecsv

И ( в отличие от первоначального вопроса) предполагая , что вы используете Python, встроенный в csvмодуль, поворот
import csvв
import unicodecsv as csvв коде.

kqw
источник
29
Это не сработало, просто заменив импорт, мне также пришлось добавить кодировку при создании писателя: writer = csv.writer(out, dialect='excel', encoding='utf-8')и создать обработчик файлов с помощью open(..., not codecs.open(... .
Сюзана
4
Я перепробовал все предложения на StackOverflow, и только это мне подходит.
Чарльз Чоу
95

Для Python 3.x это очень просто ( документы ).

import csv

with open('output_file_name', 'w', newline='', encoding='utf-8') as csv_file:
    writer = csv.writer(csv_file, delimiter=';')
    writer.writerow('my_utf8_string')

Для Python 2.x смотрите здесь .

Занон
источник
1
что, если содержимое writerowне является UTF-8? это будет работать?
CKM
1
Нет необходимости в установке сторонних пакетов.
Vaibhav Vishal
4

Для меня UnicodeWriterкласс из документации модуля Python 2 CSV на самом деле не работал, поскольку он нарушает csv.writer.write_row()интерфейс.

Например:

csv_writer = csv.writer(csv_file)
row = ['The meaning', 42]
csv_writer.writerow(row)

работает, пока:

csv_writer = UnicodeWriter(csv_file)
row = ['The meaning', 42]
csv_writer.writerow(row)

выкину AttributeError: 'int' object has no attribute 'encode'.

Поскольку, UnicodeWriterочевидно, ожидается, что все значения столбцов будут строками, мы можем преобразовать значения сами и просто использовать модуль CSV по умолчанию:

def to_utf8(lst):
    return [unicode(elem).encode('utf-8') for elem in lst]

...
csv_writer.writerow(to_utf8(row))

Или мы можем даже заплатить csv_writer, чтобы добавить write_utf8_rowфункцию - это упражнение предоставляется читателю.

Боян Богданович
источник
гораздо более простое решение для py2.x для тех из нас, кто все еще использует его.
хан
2

Примеры в документации Python показывают, как писать файлы Unicode CSV: http://docs.python.org/2/library/csv.html#examples

(здесь нельзя скопировать код, потому что он защищен авторским правом)

Аарон Дигулла
источник
1
Спасибо за ссылку. Это было полезно. Насколько мне известно, даже если вы разместили ссылку, вы не можете скопировать и вставить код сюда? (+1 за владение авторскими правами)
Mutant
1
@Mutant: Код не похож на научные статьи. Код защищен авторским правом. Хотя я на 99,999% уверен, что владельцы Python не подадут в суд на SO за копирование их кода, мне не хотелось читать их длинную лицензию, чтобы узнать, разрешено это или нет. Кроме того, хорошо время от времени напоминать людям, что «Я вижу это на моем мониторе»! = «Я могу делать с ним все, что захочу» :-)
Аарон Дигулла
1
Спасибо за напоминание. К сожалению, мир, в котором мы живем, стал настолько (необоснованно) быстрым и небрежным, где информация течет быстрее, чем можно себе представить, что он действительно требует напоминания раз и во время ограничения, которое имеет значение. Спасибо за это :)
Mutant
2
Ссылка на документы полуцелесообразна (примеры лучше), но аргумент "авторских прав" здесь преувеличен и бессмысленен. Python - это явно открытый исходный код ( v2 v3 ). Лицензия ясна: «Бесплатная всемирная лицензия на воспроизведение, анализ, тестирование, выполнение и / или публичное отображение, подготовку производных работ, распространение ... [и т. Д.]» Даже простая фраза в вверху страницы "GPL-совместимый" должен вас утешить. Делитесь материалами с открытым исходным кодом. Даже измените его, если хотите. Это открытый исходный код не зря.
alttag
@alttag Копирование или использование кода GPLd в проекте означает, что весь другой код в том же проекте теперь также находится под GPL. Поскольку я не адвокат по авторскому праву, я не знаю, что это значит в отношении кода, опубликованного на веб-сайте.
Аарон Дигулла
0

Для python2 вы можете использовать этот код до этого. csv_writer.writerows(rows)
Этот код НЕ будет преобразовывать целые числа в строки utf-8.

def encode_rows_to_utf8 (строки):
    encoded_rows = []
    для ряда в ряды:
        encoded_row = []
        для значения в строке:
            если isinstance (значение, базовая строка):
                значение = unicode (значение) .encode ("utf-8")
            encoded_row.append (значение)
        encoded_rows.append (encoded_row)
    вернуть encoded_rows
пимен
источник
-1

Очень простой прием - использовать импорт json вместо csv. Например, вместо csv.writer просто сделайте следующее:

    fd = codecs.open(tempfilename, 'wb', 'utf-8')  
    for c in whatever :
        fd.write( json.dumps(c) [1:-1] )   # json dumps writes ["a",..]
        fd.write('\n')
    fd.close()

В основном, учитывая список полей в правильном порядке, строка в формате json идентична строке csv, за исключением [и] в начале и в конце соответственно. И json кажется устойчивым к utf-8 в python 2. *

впатхак
источник