python:unicode函数vs u前缀

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)

但似乎编码在某种程度上以不同的方式完成,具体取决于使用的内容.这里发生了什么?

Mar*_*ers 5

你的问题在于你所申请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)