2013-06-28 21 views
1

我現在在Ubuntu 13.04和Python 2.7.4上,並試圖運行包含以下行的腳本:ascii編解碼器無法解碼位於Ubuntu/Python中的位置錯誤中的字節0xe3,但無法在OS X/Python上解碼

html = unicode(html, 'cp932').encode('utf-8') 
html1, html2 = html.split(some_text) # this line spits out the error 

但是,當我在Ubuntu 13.04上運行上述腳本時,它發現錯誤UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 106: ordinal not in range(128)。但是,這個完全相同的腳本總是可以在OS X 10.8和Python 2.7.3上成功執行。所以我想知道爲什麼錯誤只發生在兩個平臺之一...

我首先想到的是,特別是在看完這篇文章後(UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 1)是因爲我處於不同的LANG環境,我在OS X上使用jp_JP.UTF-8,但在Ubuntu上使用en_US.UTF-8。所以我也試着在上面提到的腳本中再增加一行os.environ['LANG'] = 'jp_JP.UTF-8',但是仍然有同樣的錯誤。

另一個奇怪的現象是,當我嘗試從Ubuntu的IPython shell中運行腳本並在錯誤發生後立即進入調試模式,然後運行最初觸發錯誤的行時,我沒有錯誤更多...

那麼這裏發生了什麼?我錯過了什麼?

在此先感謝。

+0

'some_text'中有什麼?我的猜測是它是一個「unicode」對象,而不是「str」。如果是這樣,該行將有效地調用'unicode(html).split(some_text)',而這種隱式轉換就是失敗的地方。你能記錄每個平臺上的類型和字節並看看嗎? – abarnert

+0

另外,您鏈接的問題與您的問題無關。正如接受的答案所說,用戶的問題不是關於他的代碼中的編碼和解碼,而是關於當他向終端打印時發生的隱式編碼。你不會在任何地方(或者至少不在這條線上)這麼做,所以它不會影響你。 (並且,即使它的確如此,你的兩個語言環境都使用UTF-8,所以這不會成爲問題。) – abarnert

+0

PS,你爲什麼使用'unicode(html,'cp932')。encode('utf -8' )'?混合和匹配兩種不同的轉換方式並不違法,但這絕對是奇怪的。爲什麼不'html.decode('cp932')。encode('utf-8')'? – abarnert

回答

1

你還沒有給我們足夠的信息可以肯定的,但有一個很好的機會,這是你的問題:

如果some_textunicode對象,那麼這行:

html1, html2 = html.split(some_text) # this line spits out the error 

...在str上調用split,並傳遞unicode參數。每當在相同的調用中混合使用strunicode時,Python 2.x會通過在str上自動調用unicode來處理該問題。所以,這就是等價於:

html1, html2 = unicode(html).split(some_text) # this line spits out the error 

...這相當於:

html1, html2 = html.decode(sys.getdefaultencoding()).split(some_text) # this line spits out the error 

...如果有任何非ASCII字符html,這將無法完全按照你所看到的。


簡單的解決方法是顯式編碼some_text爲UTF-8:

html1, html2 = html.split(some_text.encode('utf-8')) 

不過,我個人甚至不會嘗試與str對象來自3個不同的字符集都在同一個程序中工作。爲什麼不只是decode/encode在非常邊緣,只處理unicode到處都是對象?

+0

正如你所提到的,我確認'html'是'str','some_text'是'unicode'對象。在閱讀你的評論,特別是'sys.getdefaultencoding()'後,我發現OS X和Ubuntu的工作原理是不同的,因爲我把'sitecustomize.py'設置爲OS X上的默認編碼爲utf-8,但是不在Ubuntu上。而且我在Ubuntu上也放置了相同的文件,然後腳本成功運行。爲了您的信息'html'由urllib2.urlopen()。read()產生,我不知道它返回一個'str'類型。非常感謝。非常感謝。 – Blaszard

+0

@ user2360798:如果他們沒有另外說明,Python 2.x中的大部分內容都會返回一個'str'。但即使在3.x中,大多數情況下返回的是Unicode對象,「urlopen」仍然會返回字節,否則它將不得不猜測編碼。你下載的資源不太可能使用你的默認編碼,而且考慮到所有的編碼方式都可以被指定(HTTP標頭,HTML頭部分,根本不......),它實際上是無法猜測的,所以它留給你。 – abarnert

相關問題