2015-10-16 61 views
1

我從數據庫查詢中讀取一個值,該值生成一個unicode字符串。由於此處無關的原因,數據輸入人員將字符串值輸入到數據庫中,如「Assessor's Parcel」(注意「反向」撇號)。我正在編寫剛剛通過選定數據庫記錄並打印出文本的代碼。我使用.format()操作將變量中的文本插入到打印輸出中。衆所周知,傳遞unicode字符串時.format失敗。因此,減少這種對難題,我提出下面的例子:帶有打印和格式的unicode字符串輸出不一致()

>>> a = u"Assessor’s Parcel" 
>>> a 
u'Assessor\u2019s Parcel' 
>>> print a 
Assessor’s Parcel 
>>> "{0}".format(a) 
Traceback (most recent call last): 
    File "<interactive input>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 8: ordinal not in range(128) 
>>> 

以上線是從的PythonWin的「交互窗口」(PythonWin的2.7.5(默認情況下,22:43 2013年5月15日,: 36)在win32上[MSC v.1500 32位(Intel)]。)

爲什麼'print a'產生的輸出不僅僅是'a'?爲什麼呢,如果其中任何一個能產生合理的輸出,.format()不能?

如果我確定我不能輸出unicode文本(對於某些尚未知的原因),並且我會滿足包含「\ u」語法的輸出,那麼是否真的必須包裝我的所有字符串在某些代碼(方法或其他)中執行轉換的數據庫值的輸出?

+0

必要鏈接http://bit.ly/unipain – Daenyth

回答

2

只是use unicode! (請注意,你的錯誤是該HOWTO的第一個例子)

這個問題不是格式化,而是因爲你試圖把一個unicode對象放入一個字節串,所以它試圖對它進行編碼使用ascii的默認編碼)。相反,如果你試圖把它格式化成Unicode字符集的文字就沒有問題..

>>> a = u"Assessor’s Parcel" 
>>> '{}'.format(a) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 8: ordinal not in range(128) 
>>> u'{}'.format(a) 
u'Assessor\u2019s Parcel' 
>>> print u'{}'.format(a) 
Assessor’s Parcel 
>>> 

它也不會是一個問題,如果你把一個字節串到字節串。

>>> '{}'.format(a.encode('utf8')) 
'Assessor\xe2\x80\x99s Parcel' 
>>> print '{}'.format(a.encode('utf8')) 
Assessor’s Parcel 
>>> 

但是,這使得以後輸出到另一個(不同的)編碼更加困難。

0

簡單'a'要求類的方法中的「最原始」的值的形式。打印通過str()轉換值的驅動器。格式表達式通過另一個不同的轉換髮送它,一個當前以ASCII工作。

0

下面是我的幾次嘗試正確打印。 print a.encode('utf-8')似乎是一個解決方案:

>>> a = u"Assessor’s Parcel" 
>>> a 
u'Assessor\u2019s Parcel' 

>>> print a 
Assessor’s Parcel 

>>> "{0}".format(a) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 8: ordinal not in range(128) 

>>> a.encode('utf-8') 
'Assessor\xe2\x80\x99s Parcel' 

>>> print a..encode('utf-8') 
    File "<stdin>", line 1 
    print a..encode('utf-8') 
      ^
SyntaxError: invalid syntax 

>>> print a.encode('utf-8') 
Assessor’s Parcel 

>>> print a.encode('utf-8') 
Assessor’s Parcel 

>>> print a..encode('utf-8') 
    File "<stdin>", line 1 

    print a..encode('utf-8') 
      ^
SyntaxError: invalid syntax 

>>> a.encode('utf-8') 
'Assessor\xe2\x80\x99s Parcel' 

>>> print a.encode('utf-8') 
Assessor’s Parcel 
0

在交互式shell中,'a'確實打印出一個表示。您可以使用print repr(a)

print a將打印str(a)輸出到標準輸出。 print將始終編碼輸出,無論輸出的編碼是什麼。所以print a類似於sys.stdout.write(a.encode(sys.stdout.encoding) + "\n")

請注意u"string""string"之間的區別。首先是一個Unicode字符串 - 一個Unicode代碼點的序列,而後者是一個二進制字符串 - 一個字節序列。Python 3在兩者之間做出了更加嚴格的區分(我實際上更喜歡Python 3,因爲它更挑剔,因此更好地告訴我我做錯了什麼)

"{0}".format(a),"{0}"是一個二進制字符串。您嘗試在該二進制字符串中格式化非ASCII字符的unicode字符串。這失敗了,因爲你需要告訴Python如何從Unicode轉換爲二進制字符串。所以你可以這樣做:"{0}".format(a.encode('utf-8'))

但是,您可能不想要一個格式化的二進制字符串,而是一個格式化的Unicode字符串。在這種情況下,您可以編寫:u"{0}".format(a)