通过python csv编写utf-8?(上一个答案不起作用)
In建议使用csv文档中的一些示例代码来处理这种情况 我无法修复该代码的问题,我想知道我做错了什么 以下是我的测试代码:通过python csv编写utf-8?(上一个答案不起作用),python,python-2.7,csv,Python,Python 2.7,Csv,In建议使用csv文档中的一些示例代码来处理这种情况 我无法修复该代码的问题,我想知道我做错了什么 以下是我的测试代码: # -*- coding: UTF-8 -*- import csv import codecs import csvutf8 # sample code from csv documentation. x = u'owner’s' with codecs.open('simpleout.txt', 'wb', 'UTF_8') as of: spamwriter
# -*- coding: UTF-8 -*-
import csv
import codecs
import csvutf8 # sample code from csv documentation.
x = u'owner’s'
with codecs.open('simpleout.txt', 'wb', 'UTF_8') as of:
spamwriter = csvutf8.UnicodeWriter(of)
spamwriter.writerow([x])
csvutf8.py是我从文档中复制并粘贴代码的文件,它位于此消息的末尾
库中codecdes.py
的错误消息为:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 5: ordinal not in range(128)
我能做些什么来让它工作
csvutf8.py
"""Helper classes to output UTF_8 through CSV in Python 2.x"""
import csv, codecs, cStringIO
class UTF8Recoder:
"""
Iterator that reads an encoded stream and reencodes the input to UTF-8
"""
def __init__(self, f, encoding):
self.reader = codecs.getreader(encoding)(f)
def __iter__(self):
return self
def next(self):
return self.reader.next().encode("utf-8")
class UnicodeReader:
"""
A CSV reader which will iterate over lines in the CSV file "f",
which is encoded in the given encoding.
"""
def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
f = UTF8Recoder(f, encoding)
self.reader = csv.reader(f, dialect=dialect, **kwds)
def next(self):
row = self.reader.next()
return [unicode(s, "utf-8") for s in row]
def __iter__(self):
return self
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)
UnicodeWriter
示例代码用于从open
获取的纯字节文件,而不是从codecs.open
(或io.open
)获取的Unicode文件。最简单的修复方法是只使用open
而不是codec。在主脚本中打开
:
with open('simpleout.txt', 'wb') as of:
如果你打算在一个项目中使用
if isinstance(f, (
codecs.StreamReader, codecs.StreamWriter,
codecs.StreamReaderWriter, io.TextIOBase)):
raise TypeError(
'Need plain bytes files, not {}'.format(f.__class__))
但是如果您打算坚持使用Python 2,*在掌握窍门之前,很难发现这些错误,因此您现在应该学习如何发现它们。下面是一些具有相同错误的简单代码:
data1 = u'[owner’s]'
data2 = data1.encode('utf-8')
data3 = data2.encode('utf-8')
在交互式解释器中进行测试,并查看每个中间步骤的repr、type等。您将看到data2
是str
,而不是unicode
。这意味着它只是一堆字节。将一堆字节编码为UTF-8意味着什么?唯一有意义的**是使用默认编码(因为您没有设置任何其他内容,所以为ASCII)将这些字节解码为Unicode,这样就可以将其编码回字节
因此,当您看到其中一个关于ASCII的UnicodeDecodeError
s时(您很确定您调用的是encode
,而不是decode
),通常就是这个问题。检查调用它的类型,它可能是str
而不是unicode
***
*我认为2018年仍然使用Python2是有一个很好的理由的。如果没有,答案就简单多了:只要使用Python3,整个问题就不可能解决(代码更简单,运行更快) **如果你认为Python不去猜测你的意思会更有意义,并把这当成一个错误……你是对的,这也是Python 3存在的主要原因之一 ***当然,您仍然需要弄清楚为什么在哪里有字节
您希望使用Unicode。有时这真的很愚蠢,就像你做了
u=s.decode('latin1')
,但是你一直用s
而不是u
。有时候会有点棘手,比如这个例子,你正在使用一个自动为你编码的库,但是你没有意识到。有时甚至更糟,比如你忘记解码网站上的一些文本,它整天都在默默运行,在运行到第一个带有斯拉夫名字的页面之前,创建了数千页的mojibake,最后出现了一个错误。供将来参考:请确保你发布的代码实际上是你的代码(不能以这种方式缩进类UnicodeWriter:
,否则导入将失败,出现语法错误
),并发布回溯,而不仅仅是错误(以便有人可以知道问题发生在何处)@Martin Evans。UnicodeWriter不是Python库中的一个模块,因此不可直接导入。相反,它是一些作为示例包含在编解码器文档中的代码。过去,当我从某个地方复制示例时,我也将其包含在StackOverflow问题中。这里哪种方法合适?谢谢。