天天看點

《Python Cookbook(第2版)中文版》——1.20 使用Unicode來處理國際化文本

本節書摘來自異步社群《python cookbook(第2版)中文版》一書中的第1章,第1.20節,作者[美]alex martelli , anna martelli ravenscrof , david ascher ,高鐵軍 譯,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

任務

需要處理包含了非ascii字元的文本字元串。

解決方案

可以在一些使用普通的位元組串str類型的場合,使用python提供的内置的unicode類型。用法很簡單,隻要接受了在位元組串和unicode字元串之間的顯式轉換的方式:

這裡german_ae是一個unicode字元串,代表了小寫的德語元音變音(umlaut,或其他分音符)字元“æ”。根據指定的utf-8編碼方式,通過解析單位元組字元串'xc3xa4',這段代碼建立了一個unicode字元串。還有很多其他的編碼方式,不過utf-8最常用,因為它是最通用的(utf-8可以編碼任何unicode字元串),而且也和7位的ascii字元集相容(任何ascii單位元組字元串,也是正确的utf-8編碼字元串)。

一旦跨過這一屏障,生活就變得更美好了!可以像處理普通的str字元串那樣操縱unicode字元串:

注意,para是一個unicode字元串,這是因為一個unicode字元串和一個位元組串之間的操作總會産生一個unicode字元串—除非這個操作發生錯誤并抛出異常:

字元’0xc3’不是7位ascii編碼中的有效字元,python也拒絕猜測其編碼。是以,在python中使用unicode的關鍵點是,你要随時明确編碼是什麼。

讨論

如果你遵守一些規範,并且學會處理一些常見的問題,則python中的unicode處理是非常簡單的事情。這不是說完成一個高效的unicode實作是個簡單的任務。不過,正如其他的一些難題一樣,無須擔心太多:隻管使用python的高效的unicode實作就行了。

最重要的一點是,首先要完全接受位元組串和unicode字元串的差異。正如解決方案小節所示,你經常需要通過一個位元組串和一個編碼方式顯式地建立一個unicode字元串。不指定編碼方式,位元組串基本沒有什麼意義,除非你很有運氣而且碰巧那個位元組串是ascii文本。

在python中使用unicode字元串的最常見的問題是,你正在處理的文本一部分是unicode對象,另一部分則是位元組串。python會簡單地嘗試把你的位元組串隐式地轉換成unicode。它通常假設那些是ascii編碼,如果其中碰巧含有了非ascii字元,它會給你一個unicodedecodeerror的異常。unicodedecodeerror異常通知你,你把unicode和位元組串混在了一起,而且python無法(它根本也不會去嘗試)猜測你的位元組串代表何種文本。

各個python大項目的開發人員們總結出了一些簡單的規則,來避免這種運作時的unicodedecodeerror異常,該規則可以被總結為一句話:總是在io動作的關口做轉換。下面更深入地解釋一下。

無論何時,當你的程式接收到了來自“外部”的文本資料(來自網絡、檔案、或者使用者輸入等)時,應當立刻建立一個unicode對象,找出最适合的編碼,如檢視http頭,或者尋找一個合适的轉化方法來确定所用的編碼方式。

無論何時,當你的程式需要向“外部”發送文本資料(發到網絡、寫入檔案、或者輸出給使用者等)時,應當探察正确的編碼,并用那種編碼将你的文本轉化成位元組串。(否則,python會嘗試把unicode轉成ascii位元組串,這很有可能發生unicodeencodeerror異常,正好是前面例子中給出unicodedecodeerror的相反情況)。

遵循這兩個規則,可以解決絕大多數的unicode問題。如果你仍然遇到了那兩種unicodeerror之一,應當趕快檢查是否忘記了在什麼地方建立一個unicode對象,或者忘記了把它轉化為編碼過的位元組串,再或者使用了完全不正确的編碼方式。(編碼錯誤也有可能來自于使用者,或者其他與你的程式進行互動的程式,因為它們沒有遵循編碼規則或慣例。)

為了将一個unicode字元串轉回到編碼過的位元組串,你通常可以這麼做:

現在,bytestring是德語中的用’latin1’進行編碼的æ字元。注意,’xe4’(latin1)以及前面展示的’xc3xa4’(utf-8)代表了同樣的德語字元,但使用了不同的編碼。

至此為止,應該能夠了解為什麼python拒絕在幾百種可能的編碼中進行猜測了吧。這是一種很重要的設計選擇,基于了zen of python原則中的一條:“在模糊含混面前拒絕猜測。”在任何一個python的互動式shell提示符下,輸入import this語句,你就可以閱讀zen of python中的重要原則。