Як записати UTF-8 у файл CSV


83

Я намагаюся створити текстовий файл у форматі 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")

Але це також зупиняється, коли з’являється спеціальний персонаж. Я не уявляю, що я роблю не так.


"це salso вершини"? Що це означає? Яку помилку ви отримуєте? Який ваш внесок?

Вхідними даними є pyqt4 QTableWidgetItem. Проблема в тому, що я не отримую жодної помилки, оскільки скрипт працює як плагін.
Мартін

Потім спробуйте відтворити проблему поза QT.

Знайшли рішення. Мені довелося писатиmyfile.write(u"%s"&f+";")
Мартін

Відповіді:


106

З вашої оболонки:

pip2 install unicodecsv

І ( в відміну від початкового питання) припускаючи , що ви використовуєте Python, вбудований в csvмодуль, поворот
import csvв
import unicodecsv as csvв коді.


29
Це не спрацювало просто заміну імпорту, я також мав додати кодування при створенні письменника: writer = csv.writer(out, dialect='excel', encoding='utf-8')і створити обробник файлів з open(..., НЕ codecs.open(... .
Сузана

4
Я спробував усі пропозиції щодо StackOverflow, і тільки ця працює для мене.
Чарльз Чоу,

91

Для Python 3.x ( docs ) це дуже просто .

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


3

Для мене UnicodeWriterклас із документації модуля CSV Python 2 насправді не працював, оскільки він порушує 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функцію - вправа залишається за читачем.


2

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

(не вдається скопіювати код сюди, оскільки він захищений авторським правом)


1
Дякую за посилання. Це було корисно. Наскільки мені відомо, навіть якщо ви опублікували посилання, ви не можете скопіювати вставте код сюди? (+1 за володіння авторським правом)
мутант

1
@Mutant: Кодекс не схожий на наукові праці. Код захищений авторським правом. Хоча я на 99,999% впевнений, що власники Python не будуть подавати позов до суду за копіювання їх коду, я не хотів читати їх тривалу ліцензію, щоб з’ясувати, дозволено це чи ні. Крім того, добре час від часу нагадувати людям, що "я бачу це на своєму моніторі"! = "Я можу робити з цим що завгодно" :-)
Аарон Дігулла,

1
Дякуємо за нагадування. На жаль, світ, в якому ми живемо, став настільки (необгрунтовано) швидким і необережним, де інформація надходить швидше, ніж можна собі уявити, він вимагає нагадування один раз і в той час як про обмеження, яке має значення. Дякую за це :)
Мутант

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 = []
        для значення в рядку:
            if isinstance (значення, базовий рядок):
                value = 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. *

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.