在Python中创建utf-8的csv文件
我在Python中无法创建一个utf-8编码的csv文件。
我在查看相关文档,在示例部分,它提到:
对于其他所有编码,可以使用以下的 UnicodeReader和UnicodeWriter 类。它们在构造函数中需要一个额外的编码参数,并确保数据在真正的读取器或写入器中以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)
4 个回答
1
我之前遇到过关于csv和unicode的问题,所以在bitbucket上放了一个项目:http://bitbucket.org/famousactress/dude_csv。如果你的需求比较简单,这个可能对你有帮助哦 :)
1
你已经发现,如果使用普通的打开方式是可以工作的。
原因是你尝试把UTF-8编码了两次。第一次是在
f = codecs.open('eggs.csv', 'w', encoding="utf-8")
然后在UnicodeWriter.writeRow里又编码了一次。
# ... and reencode it into the target encoding
data = self.encoder.encode(data)
要确认这个问题,可以用你原来的代码,把那一行注释掉。
祝好!
14
你不需要使用 codecs.open
;UnicodeWriter
可以直接处理 Unicode 输入,并且会自动把所有内容编码成 UTF-8。当 UnicodeWriter
把内容写入你提供的文件时,所有内容已经是 UTF-8 编码了(所以它可以和你用 open
打开的普通文件一起使用)。
如果你使用 codecs.open
,实际上你是在把 Unicode 对象转换成 UTF-8 字符串,然后又试图把这些字符串重新编码成 UTF-8,就好像这些字符串本身是 Unicode 字符串一样,这显然是行不通的。