python與編碼

發表於2016-09-01

Python中的文字物件

Python 3.x中處理文字的物件有str, bytes, bytearray。

  • bytes和bytearray可以使用除了用作格式化的方法(format, format_map)以及幾個特殊的基於Unicode的方法(casefold, isdecimal, isidentifier, isnumeric, isprintable, encode)以外幾乎所有str的方法。
  • bytes有一個類方法,可以通過序列來構建字串,而這個方法不可以用在str上。

    Unicode和字元轉換

    採用chr可以把一個Unicode的code point轉換為字元,通過ord可以進行反向操作。

len函式計算的是字元數,不是位元組數

Python與編碼

Python內部處理編碼的方式

在Python接受我們的輸入時,總是會先轉為Unicode。而且這個過程越早越好。
然後Python的處理總是對Unicode進行的,在這個過程中,一定不要進行編碼轉換的工作。
在Python向我們返回結果時,總是會從Unicode轉為我們需要的編碼。而且這個過程越晚越好。

Python原始碼的編碼方式

Python預設使用utf-8編碼。
如果想使用一種不同的編碼方式來儲存Python程式碼,我們可以在每個檔案的第一行或者第二行(如果第一行被hash-bang命令佔用了)放置編碼宣告(encoding declaration)
# ‐*‐ coding: windows‐1252 ‐*‐

Python中使用的編碼

以上是在Windows中的測試結果,如果在GNU/Linux或者OSX中,那麼所有的結果都是UTF-8.
關於mbcs和utf-8的區別,可以參考http://stackoverflow.com/questions/3298569/difference-between-mbcs-and-utf-8-on-windows

檔案讀寫的編碼

從上面的例子可以看出,無論什麼時候都不要使用預設的編碼,因為在不同的機器上執行的時候會出現意想不到的問題。

Python如何處理來自Unicode的麻煩

Python總是通過code point來比較字串的大小,或者是否相等的。

  • Unicode中重音符號有兩種表示方法,用一個位元組表示,或者用基字母加上重音符號表示,在Unicode中他們是相等的,但是在Python中由於通過code point來比較大小,所以就不相等了。

    解決方法是通過unicodedata庫中的normalize函式,該函式的第一個引數可以接受”NFC”,’NFD’,’NFKC’,’NFKD’四個引數中的一個。
    NFC(Normalization Form Canonical Composition):以標準等價方式來分解,然後以標準等價重組之。若是singleton的話,重組結果有可能和分解前不同。儘可能的縮短整個字串的長度,所以會把’eu0301’2個位元組壓縮到一個位元組’é’。
    NFD(Normalization Form Canonical Decomposition):以標準等價方式來分解
    NFKD(Normalization Form Compatibility Decomposition):以相容等價方式來分解
    NFKC(Normalization Form Compatibility Composition):以相容等價方式來分解,然後以標準等價重組之。
    NFKC和NFKD可能會引起資料損失。

西方的鍵盤通常會鍵入儘可能短的字串,也就是說和”NFC”的結果一致,但是通過”NFC”來操作一下再比較字串是否相等比較安全。且W3C建議使用”NFC”的結果。

  • 同樣的一個字元在Unicode中有兩個不同的編碼。
    該函式會把一個單一的Unicode字元轉為另一個Unicode字元。

    又比如

    再一個例子
  • 有時候我們希望使用不區分大小寫的形式進行比較
    使用方法str.casefold(),該方法會把大寫字母轉換為小寫進行比較,比如’A’會轉為’a’,’MICRO SIGN’的’µ’會轉換為’GREEK SMALL LETTER MU’的’µ’
    在絕大部分(98.9%)情況下str.casefold()和str.lower()的結果一致。
  • 文字排序
    由於不同的語言規則,如果單純按照Python的比較code point的方式進行,那麼會出現很多不是使用者期望的結果。
    通常採用locale.strxfrm進行排序。

    編碼解碼錯誤

    如果是Python原始碼中出現瞭解碼錯誤,那麼會產生SyntaxError異常。
    其他情況下,如果發現編碼解碼錯誤,那麼會產生UnicodeEncodeError, UnicodeDecodeError異常。

幾個摘自fluent python中的有用方法

編碼探嗅Chardet

這是Python的標準模組。

參考資料:

  1. http://blog.csdn.net/tcdddd/article/details/8191464

相關文章