2014-09-22 30 views
0

我遇到了麻煩,在我的Django項目UnicodeEncodeError,並最終通過改變返回值解決問題(太多的無奈後)在故障從蟒蛇:UNICODE函數VSü前綴

return unicode("<span><b>{0}</b>{1}<span>".format(val_str, self.text)) 
__unicode__方法

return u"<span><b>{0}</b>{1}<span>".format(val_str, self.text) 

但我很困惑,爲什麼這個工作(或者說,爲什麼在首位的問題)。 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'> 

但似乎編碼以某種方式做不同的視的二手什麼。這裏發生了什麼?

+0

什麼Python版本是什麼? – 2014-09-22 20:54:32

+0

2.7。 對不起,這與Python 3現在處理字符串/ unicode的方式有所不同。 – Pterosaur 2014-09-22 20:55:35

+0

在unicode函數版本中,您將格式化爲「unicodize」。格式化的問題是什麼? – tdelaney 2014-09-22 20:55:41

回答

5

你的問題在於你申請的東西unicode();你的兩個表達式是而不是等效。

unicode("<span><b>{0}</b>{1}<span>".format(val_str, self.text)) 

適用unicode()到的結果:

"<span><b>{0}</b>{1}<span>".format(val_str, self.text) 

u"<span><b>{0}</b>{1}<span>".format(val_str, self.text) 

是等價的:

unicode("<span><b>{0}</b>{1}<span>").format(val_str, self.text) 

注意右括號的位置!

所以,你的第一個版本格式第一,只有然後轉換格式爲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) 

不要緊,你在調用的結果unicode();這個例外已經被提出。

unicode.format()格式化,另一方面有沒有這樣的問題:

>>> u'str format: {}'.format(u'unicode lating-range value works: å') 
u'str format: unicode lating-range value works: \xe5' 
+0

啊,這就是訣竅!在str上調用'format'而不是unicode會嘗試將參數轉換爲ascii,這不起作用。 – Pterosaur 2014-09-22 21:07:14