2013-04-11 2 views
3

Python Документы имеют следующий пример кода при записи файла unicode в файл csv. Я думаю, он упомянул там, что это способ сделать, поскольку модуль csv не может обрабатывать строки unicode.Python: записывать Unicode в CSV, используя UnicodeWriter

class UnicodeWriter: 
    """ 
    A CSV writer which will write rows to CSV file "f", 
    which is encoded in the given encoding. 
    """ 

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): 
     # Redirect output to a queue 
     self.queue = cStringIO.StringIO() 
     self.writer = csv.writer(self.queue, dialect=dialect, **kwds) 
     self.stream = f 
     self.encoder = codecs.getincrementalencoder(encoding)() 

    def writerow(self, row): 
     self.writer.writerow([s.encode("utf-8") for s in row]) 
     # Fetch UTF-8 output from the queue ... 
     data = self.queue.getvalue() 
     data = data.decode("utf-8") 
     # ... and reencode it into the target encoding 
     data = self.encoder.encode(data) 
     # write to the target stream 
     self.stream.write(data) 
     # empty queue 
     self.queue.truncate(0) 

    def writerows(self, rows): 
     for row in rows: 
      self.writerow(row) 

Я пишу более чем один файл и сохранить его простым, я только поставил часть моего кода, чтобы продемонстрировать, как я использую выше класс в моем коде:

def write(self): 
    """ 
    Outputs the dataset to a csv. 
    """ 
    f = codecs.open(self.filename, 'a') 
    writer = UnicodeWriter(f) 
    #with open(self.filename, 'a', encoding='utf-8') as f: 
    if self.headers and not self.written: 
     writer.writerow(self.headers) 
     self.written = True 
    for record in self.records[self.last_written:]: 
     print record 
     writer.writerow(record) 
    self.last_written = len(self.records) 
    f.close() 

Это метод внутри набора данных класса coll, который готовит набор данных до записи в csv, ранее я использовал writer = csv.writer(f), но из-за ошибок кодека я меняю свой код на использование класса UnicodeWriter.

Но моя проблема в том, что, когда я открываю файл CSV, я получаю следующее:

some_header 
B,r,ë,k,ò,w,n,i,k,_,b,s 
B,r,ë,k,ò,w,n,i,k,_,c,s 
B,r,ë,k,ò,w,n,i,k,_,c,s,b 
B,r,ë,k,ò,w,n,i,k,_,d,e 
B,r,ë,k,ò,w,n,i,k,_,d,e,-,1 
B,r,ë,k,ò,w,n,i,k,_,d,e,-,2 
B,r,ë,k,ò,w,n,i,k,_,d,e,-,3 
B,r,ë,k,ò,w,n,i,k,_,d,e,-,4 
B,r,ë,k,ò,w,n,i,k,_,d,e,-,5 
B,r,ë,k,ò,w,n,i,k,_,d,e,-,M 
B,r,ë,k,ò,w,n,i,k,_,e,n 
B,r,ë,k,ò,w,n,i,k,_,e,n,-,1 
B,r,ë,k,ò,w,n,i,k,_,e,n,-,2 

Где, как эти строки должны на самом деле должно быть что-то вроде Brëkòwnik_de-1 Я на самом деле не случается.

Чтобы дать общее представление о том, как данные сгенерирован Я хотел бы добавить следующую строку: title = unicode(row_page_title['page_title'], 'utf-8')

+1

Похож на 'isinstance (строка, basestring) == True' (должен быть массив или кортеж). –

+0

сделал утверждение, что это basestring, как я могу это исправить? –

ответ

4

Этот симптом указывает на нечто вроде кормления строку в функцию/метод, который ожидает список или кортеж ,

Метод writerows ожидает список списков, а writerow ожидает список (или кортеж), содержащий значения полей. Поскольку вы кормите его строкой, а строка может имитировать список символов, когда вы перебираете ее, вы получаете CSV с одним символом в каждом столбце.

Если ваш CSV имеет только одну колонку, вы должны использовать writer.writerow([data]) вместо writer.writerow(data). Некоторые могут задать вопрос, действительно ли вам нужен модуль csv, если у вас есть только один столбец, но модуль csv будет обрабатывать такие вещи, как запись, содержащая забавные вещи (CR/LF и другие), так что да, это хорошая идея.

+0

Да, почему я думал об использовании модуля csv infact. Я не отправляю направление. Я создаю набор данных другим классом, а затем отправляю его в csv, чтобы убедиться, что данные чистые. благодаря –

Смежные вопросы