在python中正确解码unicode时遇到问题

在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')

我有一个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')
    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对象,那么它可能会起作用,但是我想非常仔细地测试一下。我尝试了这个(以及迄今为止给出的所有其他建议),但仍然会遇到相同的错误。还有其他想法吗?