你有3個或4個或5個問題...但repr()
和unicodedata.name()
是你的朋友;他們毫不含糊地向您展示了您所得到的結果,而不會由具有不同控制檯編碼的人員通過print fubar
的結果產生混淆。 (a)從一個unicode對象開始並將unquote函數應用於該對象,或者(b)以一個str對象開始並且您的控制檯編碼不是UTF-8。
如果你說你有一個Unicode對象開始:
>>> s0 = u'%C3%A7%C3%B6asd+fjkls%25asd'
>>> print repr(s0)
u'%C3%A7%C3%B6asd+fjkls%25asd'
這是一個偶然的廢話。如果您將urllibX.unquote_YYYY()
應用於它,則會得到另一個無意義的unicode對象(u'\xc3\xa7\xc3\xb6asd+fjkls%asd'
),這會在打印時導致顯示的症狀。您應該在初始unicode對象轉換爲立即STR對象:
3210
那麼你應該解除引用它:
>>> import urllib2
>>> s2 = urllib2.unquote(s1)
>>> print repr(s2)
'\xc3\xa7\xc3\xb6asd+fjkls%asd'
縱觀前4個字節的是,它的編碼爲UTF-8。如果你做的是print s2
,如果你的控制檯期望UTF-8,但是如果它期待ISO-8859-1(又名latin1),你會看到你的症狀性垃圾(第一個字符將是A-tilde)。讓我們的公園,想了一會兒,並將其轉換爲Unicode對象:
>>> s3 = s2.decode('utf8')
>>> print repr(s3)
u'\xe7\xf6asd+fjkls%asd'
,並檢查它看到我們實際上已經得到了:
>>> import unicodedata
>>> for c in s3[:6]:
... print repr(c), unicodedata.name(c)
...
u'\xe7' LATIN SMALL LETTER C WITH CEDILLA
u'\xf6' LATIN SMALL LETTER O WITH DIAERESIS
u'a' LATIN SMALL LETTER A
u's' LATIN SMALL LETTER S
u'd' LATIN SMALL LETTER D
u'+' PLUS SIGN
看起來像你說的話,你的預期。現在我們來看看在控制檯上顯示它的問題。注意:當你看到「cp850」時不要嚇壞了;我正在做這個可移植的事情,恰好在Windows上的命令提示符下執行此操作。
>>> import sys
>>> sys.stdout.encoding
'cp850'
>>> print s3
çöasd+fjkls%asd
注意:unicode對象使用sys.stdout.encoding顯式編碼。幸運的是,s3
中的所有Unicode字符都可用該編碼(以及cp1252和latin1)表示。
請做你的嘗試幫忙一個忙,併發布執行'import sys; print sys.stdout.encoding' –
事實上,解碼本身可能工作正常,但控制檯顯示的重新編碼可能有問題。 – ncoghlan