2010-06-21 7 views
17

파이썬에서 utf-8 csv 파일을 만들 수 없습니다.파이썬에서 utf-8 csv 파일 만들기

나는 그것이 문서를의 읽으려고하고, examples section에, 그것은 말한다 :

For all other encodings the following UnicodeReader and UnicodeWriter classes can be used. They take an additional encoding parameter in their constructor and make sure that the data passes the real reader or writer encoded as UTF-8:

좋아. 그래서 나는이 코드를 가지고 :

values = (unicode("Ñ", "utf-8"), unicode("é", "utf-8")) 
f = codecs.open('eggs.csv', 'w', encoding="utf-8") 
writer = UnicodeWriter(f) 
writer.writerow(values) 

을 그리고이 오류가 점점 계속 : 그래서 나는 모든 설정 때문에 도대체 내가 뭘 잘못 이해할 수

line 159, in writerow 
    self.stream.write(data) 
    File "/usr/lib/python2.6/codecs.py", line 686, in write 
    return self.writer.write(data) 
    File "/usr/lib/python2.6/codecs.py", line 351, in write 
    data, consumed = self.encode(object, self.errors) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 22: ordinal not in range(128) 

누군가가 나에게 빛을주지하시기 바랍니다 수를 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) 
+0

그것은 문제가 seens 코덱 열기. 내가 그것을 제거하고 그냥 열어 사용하면 작동합니다. 왜? –

답변

14

codecs.open을 사용할 필요가 없습니다. UnicodeWriter은 유니 코드 입력을 받아들이고 모든 것을 인코딩하여 UTF-8로 처리합니다. UnicodeWriter이 전달한 파일 핸들에 쓰면 모든 것이 이미 UTF-8 인코딩으로되어 있으므로 (즉, open으로 연 일반적인 파일에서 작동합니다).

codecs.open을 사용하면 기본적으로 유니 코드 개체를 UnicodeWriter의 UTF-8 문자열로 변환 한 다음이 문자열에 유니 코드 문자열이있는 것처럼 다시 인코딩하여 UTF-8 문자열로 다시 인코딩해야합니다.

+0

방금 ​​파일 객체를 연 이후로 정확히 두 번 인코딩하려고 시도 했습니까? codec.open이 인코딩을 나타내는 파일 객체 스트림을 방금 열었습니까? –

+2

'codecs.open'의 문서에 따르면 : "지정된 모드를 사용하여 인코딩 된 파일을 열고 숨겨진 버전 *을 반환하여 투명한 인코딩/디코딩 *을 제공합니다.". 다른 말로하면,'코덱으로 쓰려면 파일을 열면된다.open'이라면 먼저 UTF-8로 쓰는 모든 것을 투명하게 인코딩 할 것입니다. –

+0

"투명 인코딩/디코딩 제공"이 너무 주관적이라고 생각했습니다. 나는 내가 더 많이 이해할 필요가 있으면 나는 그 근원을 읽어야한다고 생각한다. –

0

모든 것을 "이중 인코딩"할 필요가 없습니다.

응용 프로그램이 완전히 유니 코드로 작동해야합니다.

외부 파일에 UTF-8 바이트를 쓰려면 codecs.open에서만 인코딩을 수행하십시오. 응용 프로그램 내에서 다른 인코딩을 수행하지 마십시오.

+1

Csv 모듈이 유니 코드와 함께 작동하지 않습니다. 내 코드를 작동 시키려면 정확히 codecs.open을 제거해야한다. –

+0

CSV가 유니 코드와 함께 작동하지 않는 경우 자체 UTF-8 엔코더를 작성하지 않는 한 UTF-8을 만들 때 CSV를 사용할 수 없습니다. –

1

일반 열기를 사용하는 경우 효과가 있음을 알았으므로

이유는 UTF-8을 두 번 인코딩하려고했기 때문입니다. 이 작품은 원래의 코드를 사용하고 그 선을 outcomment 한번

f = codecs.open('eggs.csv', 'w', encoding="utf-8") 

에서 다음 나중에 UnicodeWriter.writeRow

# ... and reencode it into the target encoding 
data = self.encoder.encode(data) 

에서 확인하십시오.

Greetz