在python中正确解码unicode时遇到问题
我有一个python脚本,它使用xlwt/xlrd处理excel文件。在脚本的开头,我有以下代码:在python中正确解码unicode时遇到问题,python,excel,unicode,xlrd,xlwt,Python,Excel,Unicode,Xlrd,Xlwt,我有一个python脚本,它使用xlwt/xlrd处理excel文件。在脚本的开头,我有以下代码: #if you got a csv in parameters, convert it to an xls file if '.csv' in sys.argv[1]: #name of new file after conversion is finished name = sys.argv[1] csvfile = open(sys.argv[1], 'rb')
#if you got a csv in parameters, convert it to an xls file
if '.csv' in sys.argv[1]:
#name of new file after conversion is finished
name = sys.argv[1]
csvfile = open(sys.argv[1], 'rb')
try:
#extract data from .csv
csvReader = csv.reader(csvfile, delimiter=' ', quotechar='|')
csvData = list(csv.reader(open(name, 'rb')))
# write to a xls file
outFile = xlwt.Wrokbook()
newSheet = outFile.add_sheet('Sheet 1')
# traverse over 2d array to write each individual cell
for row in range(len(csvData)):
for col in range(len(csvData[0])):
newSheet.write(row, col, csvData[row][col].encode('utf8'))
name = name[:-4] + ".xls" #change extension of file
outFile.save(name)
wb = open_workbook(name)
finally:
csvfile.close()
这就产生了错误
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 44: ordinal not in range(128)
在outFile.save(名称)行上
到目前为止,我发现唯一有用的东西是,但我的终端使用utf8作为编码
编辑:
完全忘了提这件事,很抱歉
我相信带.encode的行不知怎么会导致错误,但我想不出是怎么回事。我最初没有使用.encode,然后添加了.encode('utf8'),还尝试了.encode('utf-8')和unicode(字符串,'utf8')。我不知道还有什么办法来解决这个问题
编辑:
我试过布赖恩的建议,但没有结果。此外,我尝试了codecs.open建议,并在创建工作簿时尝试指定编码。这些都不能改变错误。我唯一尝试过的改变错误的方法是在newSheet.write行中添加.encode。没有它,我得到:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2013' in position 44: ordinal no in range(128)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 44: ordinal not in range(128)
通过它,我得到:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2013' in position 44: ordinal no in range(128)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 44: ordinal not in range(128)
根据报告:
csv模块不直接支持读取和写入Unicode,
但它是8位干净的,除了ASCII NUL的一些问题
人物。因此,您可以编写函数或类来处理
只要您避免像这样的编码,就可以为您进行编码和解码
使用NUL的UTF-16。建议使用UTF-8
尝试以下代码段,该代码段为您提供了一个生成器,用于读取带有unicode数据的csv。请注意,此代码直接取自上面链接的文档:
import csv
def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
# csv.py doesn't do Unicode; encode temporarily as UTF-8:
csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
dialect=dialect, **kwargs)
for row in csv_reader:
# decode UTF-8 back to Unicode, cell by cell:
yield [unicode(cell, 'utf-8') for cell in row]
def utf_8_encoder(unicode_csv_data):
for line in unicode_csv_data:
yield line.encode('utf-8')
作为如何使用上述代码的示例,而不是
csvReader = csv.reader(csvfile, delimiter=' ', quotechar='|')
使用
是生成器函数的等效返回值。该函数返回一个生成器对象,它是python中的一种iterable类型
**kwargs
表示关键字参数,当您编写delimiter='',quotechar='|'
时,实际传递的是关键字参数。问题是,当输入中包含非ascii字符时,您没有以预期的状态将它们传递给xlwt
根据xlwt的文件:
unicode实例按原样编写。str实例使用创建工作簿实例时指定的编码(默认值:“ascii”)转换为unicode
也就是说,当您的输入csv文件包含使用utf-8编码的非ascii字符时,读取器将其作为编码的Python字符串拉入—如果您直接查看它,您将看到多个十六进制字节,例如小写a-acute的'\xc3\xa1'
。当您将其写入工作表时,它必须对其进行解码。创建工作簿时,您没有指定编码,因此它尝试使用默认的ascii
编码。正如您所看到的,这不起作用,因为这些不是ascii字节
您可以选择将Unicode字符串传递到工作表,从csv读取器的结果中对其进行解码(或者将csv读取器包装在解码所有内容的东西中-这是同一件事),或者在创建工作簿时在工作簿上设置编码。尝试使用内置编解码器库打开文件:
#!/usr/bin/env python2.7
# -*- coding: UTF-8 -*-
import codecs
with codecs.open(sys.argv[1], "rb", encoding="utf-8") as csvfile:
csvReader = csv.reader(csvfile, delimiter=' ', quotechar='|')
# snipped the rest of the code
csvData[row][col]。解码('utf8')
可能吗?假设这是抛出错误的行。什么版本的python?抱歉,这是错误的,我忘记了我必须部署的服务器使用的是python 2.4。下面的答案对2.4仍然有效。我不太理解您的代码在做什么Brian,我该如何使用该代码?我以前从未见过**kwargs或yield。我认为这是错误的-示例生成器适用于CSV数据本身是Python unicode对象的情况,而不是utf-8编码的字符串的情况。因此,对输入的unicode\u csv\u数据进行编码。如果文件是用codecs.open
打开的,因此在迭代时返回Unicode对象,那么它可能会起作用,但是我想非常仔细地测试一下。我尝试了这个(以及迄今为止给出的所有其他建议),但仍然会遇到相同的错误。还有其他想法吗?