Pte*_*aur 0 python unicode string-formatting character-encoding
我UnicodeEncodeError
在我的Django项目中遇到了麻烦,最后通过更改故障__unicode__
方法的返回值来解决问题(经过多次挫折)
return unicode("<span><b>{0}</b>{1}<span>".format(val_str, self.text))
Run Code Online (Sandbox Code Playgroud)
至
return u"<span><b>{0}</b>{1}<span>".format(val_str, self.text)
Run Code Online (Sandbox Code Playgroud)
但我很困惑为什么这样做(或者更确切地说,为什么首先出现问题).做u
前缀和unicode
功能做不一样的事?在控制台中尝试时,它们似乎给出了相同的结果:
# with the function
test = unicode("<span><b>{0}</b>{1}<span>".format(2,4))
>>> test
u'<span><b>2</b>4<span>'
>>> type(test)
<type 'unicode'>
# with the prefix
test = u"<span><b>{0}</b>{1}<span>".format(2,4)
>>> test
u'<span><b>2</b>4<span>'
>>> type(test)
<type 'unicode'>
Run Code Online (Sandbox Code Playgroud)
但似乎编码在某种程度上以不同的方式完成,具体取决于使用的内容.这里发生了什么?
你的问题在于你所申请unicode()
的内容 ; 你的两个表达式不等同.
unicode("<span><b>{0}</b>{1}<span>".format(val_str, self.text))
Run Code Online (Sandbox Code Playgroud)
适用unicode()
于以下结果:
"<span><b>{0}</b>{1}<span>".format(val_str, self.text)
Run Code Online (Sandbox Code Playgroud)
而
u"<span><b>{0}</b>{1}<span>".format(val_str, self.text)
Run Code Online (Sandbox Code Playgroud)
相当于:
unicode("<span><b>{0}</b>{1}<span>").format(val_str, self.text)
Run Code Online (Sandbox Code Playgroud)
注意右括号的位置!
所以,你的第一个版本的第一格式,并且只有然后格式化为Unicode的结果转换.这是一个重要的区别!
str.format()
与unicode
值一起使用时,会传递这些值,这些值会将这些字符串str()
隐式编码为ASCII.这会导致您的异常:
>>> 'str format: {}'.format(u'unicode ascii-range value works')
'str format: unicode ascii-range value works'
>>> 'str format: {}'.format(u"unicode latin-range value doesn't work: å")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe5' in position 40: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
你调用unicode()
结果并不重要; 这个例外已经提出来了.
unicode.format()
另一方面,格式化没有这样的问题:
>>> u'str format: {}'.format(u'unicode lating-range value works: å')
u'str format: unicode lating-range value works: \xe5'
Run Code Online (Sandbox Code Playgroud)