如何在Python中正确处理Unicode字符以避免错误?
我正在为Google快速搜索框开发一个Python插件,但它在处理非ASCII字符时出现了一些奇怪的问题。我的代码在处理非ASCII字符之前都运行得很好,但一旦我尝试构建一个包含这些字符的字符串(我用的测试字符是ü),就出问题了。我使用了下面的代码片段来构建这个字符串,new_task是从GQSB输入的变量。
the_sig = ("%sapi_key%sauth_token%smethod%sname%sparse%stimeline%s" %
(api_secret, api_key, the_token, method, new_task, doParse, timeline))
它给了我这个错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
我理解这个错误的原因是因为我试图在一个ASCII字符串中拼接一个Unicode字符。网上找到的所有资料都告诉我在代码顶部声明编码,像这样:
# -*- coding: iso-8859-15 -*-
我确实这么做了。而且当我把构建字符串的代码片段放到一个新的脚本中时,它运行得很好。但不知道为什么,在其他代码的上下文中,它每次都会失败。我唯一能想到的原因是它在自己的类里面,但这对我来说没有任何意义。
完整的代码可以在GitHub上找到,点击这里。
提前感谢任何帮助。我对此感到很困惑。
3 个回答
这有点超出我的专业范围,不过我觉得 # -*- coding: iso-8859-15 -*-
这行代码是在文件最上面用来声明你的Python源文件保存时使用的文本编码格式。
那这个文件真的就是用iso-8859-15编码保存的吗?
我猜你是在使用Python 2.x版本。
文件编码声明是用来告诉解释器如何读取字符串的内容。
你应该把所有字符串都当作unicode
类型来处理,而不是str
类型。如果你从外部读取了一个str
,你需要明确地把它解码成unicode
。输出字符串的时候也是一样的。
# -*- coding: utf-8 -*-
u_dia_str = '\xc3\xbc' # str
lambda_unicode = u'λ' # unicode
# input value
u_dia = u_dia_str.decode('utf-8')
sig_unicode = u'%s%s' % (u_dia, lambda_unicode)
# => u'üλ'
# output value
sig_str = sig_unicode.encode('utf-8')
# => '\xc3\xbc\xce\xbb'
要解决这个问题,你需要做几件事。
把所有包含非ASCII字符的字符串转换成Unicode字符串。比如:
u'über'
。在处理过程中使用Unicode。换句话说,如果你收到一个编码过的字符串(不管是什么编码),在处理之前先把它解码成Unicode。比如:
s = utf8_string.decode('utf8') + latin1_string.decode('latin1')
当你要输出这个字符串或者发送到其他地方时,使用接收方能理解的编码进行编码。比如:
send(s.encode('utf8'))
。
完整的例子:
input1 = get_possibly_nonascii_input().decode('iso-8859-1')
input2 = get_possibly_nonascii_input().decode('iso-8859-1')
input3 = u'üvw'
s = u'%s -> %s' % (input3, (input1 + input2).upper())
send_output(s.encode('utf8'))