繁体   English   中英

Python:“ ascii”编解码器无法解码字节

[英]Python: 'ascii' codec can't decode byte

当前代码:

 file.write("\"" + key + "\": " + "\"" + french[key].encode('utf8') + "\"" + ',' + '\n')

字典中的法语键值如下所示:

"YOU_HAVE_COMPLETED_ENROLLMENT": "Vous avez termin\u00e9 l'inscription !"

收到此错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 19: ordinal not in range(128)

在这里尝试了所有解决方案,但似乎都没有用。

解决方案: 编码之前连接unicode字符串,然后在写入文件之前对完整的字符串进行编码。 codecs库为您简化了此过程。

import codecs

file = codecs.open(os.path.join(fr_directory, 'strings.json'), 'w+', encoding='utf8')
file.write("\"" + key + "\": " + "\"" + french[key] + "\"" + ',' + '\n')

我使用codecs.open而不是open了文件,指定当您编写unicode字符串时,该文件应自动处理UTF-8编码。 我还删除了您使用的显式编码调用。

进一步说明:

字典的键和值几乎可以肯定是Unicode字符串。 必须先对“ Unicode字符串”进行编码,然后才能将其写入文件。 除非另有说明,否则Python 2中的大多数操作都采用ASCII编码,并且其中包含open返回的文件对象。 这就是为什么,如果您尝试将Unicode字符串写入文件,则会看到异常:

>>> with open('/tmp/test.txt', 'w') as f:
...    f.write(u"Vous avez termin\xe9 l'inscription !")
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 16: ordinal not in range(128)

您可以通过直接对字符串进行编码来解决此错误,因此可以正常工作:

>>> with open('/tmp/test.txt', 'w') as f:
...    f.write(u"Vous avez termin\xe9 l'inscription !".encode('utf-8'))

但是,仅此一项并不能解决您的问题,因为您正在尝试构建更复杂的字符串。 当您将Unicode字符串连接到UTF-8编码的“原始”字符串时,即使没有写入文件,您也会遇到异常:

>>> u"YOU_HAVE_COMPLETED_ENROLLMENT: " + u"Vous avez termin\xe9 l'inscription !".encode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 16: ordinal not in range(128)

您可以通过编码任何字符串来解决此问题:

>>> u"YOU_HAVE_COMPLETED_ENROLLMENT: " + u"Vous avez termin\xe9 l'inscription !"
u"YOU_HAVE_COMPLETED_ENROLLMENT: Vous avez termin\xe9 l'inscription !"

但是,当您要将其写入文件时,必须再次对整个事情进行编码:

>>> with open('/tmp/test.txt', 'w') as f:
...    line = u"YOU_HAVE_COMPLETED_ENROLLMENT: " + u"Vous avez termin\xe9 l'inscription !"
...    f.write(line.encode('utf-8'))

但是为了方便起见, codecs模块为您提供了不必总是每次都重新编码的工具:

>>> import codecs
>>> with codecs.open('/tmp/test.txt', 'w', encoding='utf8') as f:
...    f.write(u"YOU_HAVE_COMPLETED_ENROLLMENT: " + u"Vous avez termin\xe9 l'inscription !")

您可以使用此功能对字符串进行编码

def _parse_value(value):
    if type(value) == str:
        value = value.decode("utf-8", "ignore").strip()
    return value

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM