【问题标题】:How to avoid unicodeError?如何避免 unicodeError?
【发布时间】:2026-02-10 06:05:03
【问题描述】:

我正在尝试写入文件并收到以下错误:

Traceback (most recent call last):
  File "/private/var/folders/jv/9_sy0bn10mbdft1bk9t14qz40000gn/T/Cleanup At Startup/merge-395780681.888.py", line 151, in <module>
    gc_all_d.writerow(row)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py", line 148, in writerow
    return self.writer.writerow(self._dict_to_list(rowdict))
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0329' in position 5: ordinal not in range(128)

在我尝试将咨询师数据库中的一行写入聚合他们姓名的文件后,出现错误:

# compile master spreadsheet
with(open('gc_all.txt_3','w')) as gc_all:
    gc_all_d = csv.DictWriter(gc_all,  fieldnames = fieldnames, extrasaction='ignore', delimiter = '\t') 
    gc_all_d.writeheader()
    for row in aicep_l:
        print row['name']
        gc_all_d.writerow(row)
    for row in nbcc_l:
        gc_all_d.writerow(row)
        print row['name']

我在这里是陌生的水域。我在 writerow() 方法中没有看到可以将编码范围扩大到这个字符 '\u0329' 的参数。

我认为该错误可能与我使用名称解析器模块将所有辅导员姓名组织成相同格式的事实有关。从 nameparser 导入的 HumanName 函数可能会写出带有前导 'u' 的辅导员姓名以表示 unicode,这意味着无法识别总输出 u'Sam the Man' 而不是 'Sam the Man'。

感谢您的帮助!


根据答案修改后出现错误:

  File "/private/var/folders/jv/9_sy0bn10mbdft1bk9t14qz40000gn/T/Cleanup At Startup/merge-395782963.700.py", line 153, in <module>
    row['name'] = row['name'].encode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xcc in position 11: ordinal not in range(128)

使所有名称条目统一的代码:

# nbcc
with(open('/Users/samuelfinegold/Documents/noodle/gc/nbcc/nbcc_output.txt', 'rU')) as nbcc:
    nbcc_d = csv.DictReader(nbcc, delimiter = '\t')
    nbcc_l = []
    for row in nbcc_d:
#         name = HumanName(row['name'])
#         row['name'] = name.title + ' ' + name.first + ' ' + name.middle + ' ' + name.last + ' ' + name.suffix       
        row['phone'] = row['phone'].translate(None, whitespace + punctuation)
        nbcc_l.append(row)

修改代码:

# compile master spreadsheet
with(open('gc_all.txt_3','w')) as gc_all:
    gc_all_d = csv.DictWriter(gc_all,  fieldnames = fieldnames, extrasaction='ignore', delimiter = '\t') 
    gc_all_d.writeheader()
    for row in nbcc_l:
        row['name'] = row['name'].encode('utf-8')
        gc_all_d.writerow(row)

错误:

Traceback (most recent call last):
  File "/private/var/folders/jv/9_sy0bn10mbdft1bk9t14qz40000gn/T/Cleanup At Startup/merge-395784700.086.py", line 153, in <module>
    row['name'] = row['name'].encode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xcc in position 11: ordinal not in range(128)
logout

【问题讨论】:

标签: python parsing utf


【解决方案1】:

来自docs

此版本的 csv 模块不支持 Unicode 输入。此外,目前还有一些关于 ASCII NUL 字符的问题。因此,为了安全起见,所有输入都应该是 UTF-8 或可打印的 ASCII;请参阅示例部分中的示例。

您需要在写入数据之前对其进行编码 - 例如:

for row in aicep_1:
    print row['name']
    for key, value in row.iteritems():
        row[key] = value.encode('utf-8')
    gc_all_d.writerow(row)

或者,由于您使用的是 2.7,您可以使用字典理解:

for row in aicep_1:
    print row['name']
    row = {key, value.encode('utf-8') for key, value in row.iteritems()}

或者在文档的示例页面上使用一些更复杂的模式。

【讨论】:

  • 文件 "/private/var/folders/jv/9_sy0bn10mbdft1bk9t14qz40000gn/T/Cleanup At Startup/merge-395782963.700.py",第 153 行,在 row['name'] = row[ 'name'].encode('utf-8') UnicodeDecodeError: 'ascii' codec can't decode byte 0xcc in position 11: ordinal not in range(128)
  • 完整的上下文是什么?如果您已经对某些内容进行了编码,然后尝试对其进行重新编码,则可能会发生这种情况,如下所述:*.com/questions/9644099/… - 所以这取决于您获取行的位置。
  • 嗯,完整的上下文...所以我运行这个: for row in nbcc_l: # print type(row) row['name'] = row['name'].encode ('utf-8') gc_all_d.writerow(row 并且所有行都是 type = 'unicode'。所以我不确定错误是否相同。
  • 评论不能很好地处理代码 - 最好的展示方式是将其编辑到帖子中。但是,仔细观察它,这不是正确的解决方案,除非row 只有一个元素。而且我看到我在回答中忽略了您正在使用DictWriter - 我将对其进行编辑以更正。
  • 认为我已经在这样做了。 'name' 是所有更改值的键。
【解决方案2】:

您拥有的是一个输出流(您的gc_all.txt_3 文件,在with 行上打开,变量gc_all 中的流实例),Python 认为它必须只包含ASCII。您已经要求它编写一个带有 Unicode 字符 '\u0329' 的 Unicode 字符串。例如:

>>> s = u"foo\u0329bar"
>>> with open('/tmp/unicode.txt', 'w') as stream: stream.write(s)
...

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0329' in position 3:
ordinal not in range(128)

您有很多选择,包括对每个字符串执行明确的.encode。或者,您可以使用codecs.open 打开文件,如http://docs.python.org/2/howto/unicode.html 中所述(我假设Python 2.x,3.x 有点不同):

>>> import codecs
>>> with codecs.open('/tmp/unicode.txt', 'w', encoding='utf-8') as stream:
...     stream.write(s)
... 
>>> 

编辑添加:根据@Peter DeGlopper 的回答,明确的encode 可能更安全。 UTF-8 在其编码中没有 NUL,因此假设您想要 UTF-8,通常是这样,这可能没问题。

【讨论】: