4

我一直在用特殊字符(捷克字母)解析一些 docx 文件(UTF-8 编码的 XML)。当我尝试输出到标准输出时,一切都很顺利,但我无法将数据输出到文件中,

回溯(最近一次调用):
文件“./test.py”,第 360 行,in
ofile.write(u'\t\t\t\t\t\n')
UnicodeEncodeError: 'ascii' codec can't在位置 37 编码字符 u'\xed':序数不在范围内(128)

尽管我将word变量显式转换为 unicode 类型(type(word)返回的 unicode),但我尝试对其进行编码,但.encode('utf-8)仍然遇到此错误。

这是现在看起来的代码示例:

for word in word_list:
    word = unicode(word)
    #...
    ofile.write(u'\t\t\t\t\t<feat att="writtenForm" val="'+word+u'"/>\n')
    #...

我还尝试了以下方法:

for word in word_list:
    word = word.encode('utf-8')
    #...
    ofile.write(u'\t\t\t\t\t<feat att="writtenForm" val="'+word+u'"/>\n')
    #...

甚至这两者的结合:

word = unicode(word)
word = word.encode('utf-8')

我有点绝望,所以我什至尝试在ofile.write()

ofile.write(u'\t\t\t\t\t<feat att="writtenForm" val="'+word.encode('utf-8')+u'"/>\n')

我会很感激任何关于我做错了什么的提示。

4

4 回答 4

11

ofile是一个字节流,您正在向其写入字符串。因此,它尝试通过编码为字节字符串来处理您的错误。这通常只对 ASCII 字符是安全的。由于word包含非 ASCII 字符,因此失败:

>>> open('/dev/null', 'wb').write(u'ä')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 0:
                    ordinal not in range(128)

通过使用、 模式和显式编码ofile打开文件来创建文本流:io.open'wt'

>>> import io
>>> io.open('/dev/null', 'wt', encoding='utf-8').write(u'ä')
1L

或者,您也可以使用codecs.open几乎相同的界面,或者使用encode.

于 2012-11-22T12:13:41.807 回答
2

菲哈格的回答是正确的。我只是想建议使用显式编码手动将 unicode 转换为字节字符串:

ofile.write((u'\t\t\t\t\t<feat att="writtenForm" val="' +
             word + u'"/>\n').encode('utf-8'))

(也许你想知道它是如何使用基本机制而不是高级巫术和黑魔法来完成的io.open。)

于 2012-11-22T12:32:59.453 回答
2

在写入 word 文档 (.docx) 时,我遇到了类似的错误。特别是欧元符号 (€)。

x = "€".encode()

这给出了错误:

UnicodeDecodeError:“ascii”编解码器无法解码位置 0 的字节 0xe2:序数不在范围内(128)

我是如何解决的:

x = "€".decode()

我希望这有帮助!

于 2014-11-30T20:49:28.253 回答
1

我在stackoverflow中找到的最佳解决方案是在这篇文章中: 如何修复:“UnicodeDecodeError:'ascii'编解码器无法解码字节” 放在代码的开头,默认编码将是utf8

# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
于 2016-11-14T12:59:54.627 回答