我有一个带有和端点的Python服务,它将数据传递给另一个服务,获取结果并将其传递给请求者。在表单中有一个字段message
,如果我输入一个Unicode字符 - 让我们说'用微笑眼睛擦脸'(U + 1F601) - 我在请求表单对象中看到了以下内容
ImmutableMultiDict([('message', u'\U0001f601'),...
当我收到其他服务的回复时,我有这个
{..., u'message': u'\xf0\x9f\x98\x81',...}
然后使用json.dumps将其JSONified转换为
{..."message": "\u00f0\u009f\u0098\u0081"...}
最后,在客户端上,消息字符串被解析为
ð
(如果我没记错的话,那个字符的Unicode代码是\u00f0
)
那么哪里出错了?看起来我有一个字符串,从外部服务返回utf8十六进制转义。我尝试utf8解码该字符串,但我收到以下错误
return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not inrange(128)
答案 0 :(得分:0)
要正确处理此问题,您需要修复创建u'\xf0\x9f\x98\x81'
mojibake的过程。如上所述,这些字节是正确的,但它们需要是一个普通的字符串(在Python 3中是bytes
字符串)不是一个Unicode字符串。我们无法在不查看相关代码的情况下提供更多详细信息。
但是,您可以通过将其编码为Latin 1从mojibake中提取字节代码,然后将这些字节解码为UTF-8以创建正确的Unicode:
d = {u'message': u'\xf0\x9f\x98\x81'}
for k, v in d.items():
# Extract bytes from mojibake Unicode
b = v.encode('latin1')
# Now decode the extracted bytes as UTF-8
s = b.decode('UTF-8')
print k, s
<强>输出强>
message
或者以更紧凑的形式:
v = u'\xf0\x9f\x98\x81'
s = v.encode('latin1').decode('utf-8')
print(s)
这将适用于Python 2&amp; 3。
您应该认真考虑迁移到Python 3,其中Unicode处理非常灵巧,并且您创建这些混淆的可能性要小得多。