五分鐘戰勝 Python 字元編碼

LittleCoder發表於2016-06-27

對於很多接觸Python的人而言,字元的處理和語言整體的溫順可靠相比顯得格外桀驁不馴難以駕馭。

本文不談複雜的理論,就經驗教你字元處理八字真言:確定編碼,同類互動。

文章針對Python 2.7,主要因為3對的編碼已經有了很大的改善並且實際原理一樣,更改一下操作命令即可。

瞭解完本文,你可以輕鬆解決文書處理,特殊平臺(Windows?)下的編碼,爬蟲編碼等問題。

閱讀建議

本文分為如下幾個部分:

  • 原理
  • 具體操作
  • 建議的使用習慣
  • 疑難問題解答

如果想要了解我給出的使用習慣,可以直接跳到建議的使用習慣。

如果只想要解決相關問題可以直接跳到疑難問題解答。

希望本文能夠幫到你。

原理

為了理解方便,這裡不談理論只做類比,具體想要進一步瞭解各種編碼的理論的搜狗一下好了。

首先說一下我們為什麼會碰到各式各樣的編碼問題:

  • 因為我們沒有統一編碼
  • 因為我們沒有用對命令(傳對資料)

再說一下編碼是什麼,Python的編碼看似複雜,實際上可以看做只有兩類編碼:Unicode,二進位制

  • Unicode 相信都很熟悉:,就是\u0000這樣的
  • 二進位制編碼也很簡單,就是\x00\x00這樣的,平常看到的utf-8,cp936都是二進位制編碼
  • 二進位制編碼是具象的,10001100原樣就可以儲存,而Unicode是抽象的,不能這樣存

再說怎麼做,就是隻有同種編碼之間才可以操作

  • 舉個簡單的類比
  • 這裡說的同種就是我們熟悉的各種編碼方式:utf-8,unicode,ucs-bom
  • 這也就是編碼問題的核心,非常重要。

最後說一下Python的環境

  • 本身程式碼是用Ascii解碼的,檔案裡有Ascii無法解碼的內容的話要告知Python怎麼解碼
  • 內部大量命令都是預設接受Unicode

具體操作

拿到各種編碼的內容自然是不用說,那麼如果我們想要自己構造怎麼做呢,看下面:

那麼他們之間怎麼轉換呢,同樣很簡單:

那麼怎麼樣會出現問題呢:

所以我們需要確定程式使用的編碼,這是我們需要告訴程式的東西

  • 一方面在操作字串的時候確定是同種編碼
  • 另一方面在使用非自己寫的命令時,一般使用Unicode,或者使用接收二進位制編碼的命令

我建議的使用習慣

相信到這裡我已經把我對於編碼的理解講完了。

我們為什麼會碰到各式各樣的編碼問題:

  • 因為我們沒有統一編碼
  • 因為我們沒有用對命令(傳對資料)

所以這裡再重申一下八字真言:確定編碼,同類互動

  • 碰到問題,問一下自己,我現在是哪種編碼
  • 同一種編碼才能互動,那我應該是哪種編碼

這裡給出我的使用習慣:

  • 確定一種內部編碼
  • 內部編碼的選擇優先順序如下:程式必須使用的編碼、第三方包使用的編碼、你喜歡的編碼、Unicode
  • 在輸出時再更改到特定的編碼

記得在開始整個程式之前確定內部的編碼,否則編碼一團糟會產生很多不必要的bug。

不要迷信內部Unicode,例如Evernote開發就應該根據第三方包使用的Utf8確定內部編碼。

疑難問題解答

編碼識別

說了要確定編碼,那麼拿到一串二進位制要怎麼確定編碼呢?

最簡單的方法是chardet:(需要安裝)

使用非常簡單:

另外例如抓取網站,那麼標頭檔案中很有可能有提示如何解碼,記得不要忘記了。

編碼轉換

很可能因為字串中參雜了奇怪的東西,導致即使編碼種類正確,依舊無法解碼。

我知道我之前講過了,但可能有人直接跳疑難問題解答嘛。

這裡可以使用decode的第二個引數:

特殊平臺下編碼

很多人都說Windows是個坑,即使在Python 3下面也一樣。

因為中文檔名出來都是亂碼。

這裡使用一個取巧的方法:平臺編碼再特殊,起碼命令列讀取和建立一個資料夾不會出亂碼吧。

同樣的輸入輸出也可以這樣做優化:

檔案寫入

如果抓下來一個內容不知道怎麼解碼,但還是想要寫入檔案怎麼辦

寫入檔案的時候制定用二進位制命令即可:

裸Unicode字元

Unicode存成六個Ascii字元怎麼辦?其實也可以decode

結束語

希望讀完這篇文章能對你有幫助,有什麼不足之處萬望指正(鞠躬)。

有什麼想法或者想要關注我的更新,歡迎來GithubStar或者Fork我的專案。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

五分鐘戰勝 Python 字元編碼

相關文章