python 編碼亂碼問題(decode,encode)
ANSI:
ANSI字串我們最熟悉,英文佔一個位元組,漢字2個位元組,以一個\0結尾,常用於txt文字檔案Unicode:
- Unicode字串每個字元(漢字、英文字母)都佔2個位元組,以2個連續的\0結尾;
- NT作業系統核心用的是這種字串,常被定義為typedef unsigned short wchar_t;所以我們有時常會見到什麼char無法轉換為unsigned short之類的錯誤,其實就是unicode。
- little endian: 最低位地址存放低位位元組,可稱低位優先,記憶體從最低地址開始按順序存放(低數位數字先寫)。最低位位元組放最前面。
- big endian: 最低位地址存放高位位元組,可稱高位優先,記憶體從最低地址開始按順序存放(高數位數字先寫)。最高位位元組放最前面。
UTF8:
UTF8是Unicode一種壓縮形式。- 英文A在unicode中表示為0x0041,老外覺得這種儲存方式太浪費,
因為浪費了50%的空間,於是就把英文壓縮成1個位元組,成了utf8編碼,但是漢字在utf8中佔3個位元組,
顯然用做中文不如ANSI合算,這就是中國的網頁用作ANSI編碼而老外的網頁常用utf8的原因。
- 英文A在unicode中表示為0x0041,老外覺得這種儲存方式太浪費,
簽名BOM:
BOM 是 Byte Order Mark 的縮寫(位元組順序標記),是編碼方案裡用於標識編碼的標準標記。- ANSI 檔案沒有 BOM
- UTF-8 檔案的 BOM 為:EF BB BF,不過 UTF-8 檔案可以有 BOM,也可以沒有 BOM
- Unicode big endian 檔案的 BOM 為:FE FF
- Unicode little endian 檔案的 BOM 為:FF FE
以上是各編碼常識。
錯誤程式碼:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
字串在python內部的表示是unicode編碼,因此,在做編碼轉換時,通常需要unicode作為中間編碼,即先將其他編碼的字串解碼(decode) 成unicode,再從unicode 編碼(encode) 成另一種編碼。
- decode: 將其他編碼的字串轉換成unicode編碼,如str1.decode(‘gb2312’),表示將gb2312編碼的字串str1轉成unicode編碼。
- encode:
因此 :轉碼的時候一定要先搞明白,字串str是什麼編碼,然後decode成unicode,然後再encode成其他編碼
- 如:s=’中文’
如果是在utf8的檔案中,該字串就是utf8編碼,如果是在gb2312的檔案中,則其編碼為gb2312。這種情況下,要進行編碼轉換,都需 要先用decode方法將其轉換成unicode編碼,再使用encode方法將其轉換成其他編碼。通常,在沒有指定特定的編碼方式時,都是使用的系統默 認編碼建立的程式碼檔案。 - 如:s=u’中文’
則該字串的編碼就被指定為unicode了,即python的內部編碼,而與程式碼檔案本身的編碼無關。因此,對於這種情況做編碼轉換,只需要直接使用encode方法將其轉換成指定編碼即可。
以下,關於python 相關編碼程式碼解釋:
# -*- coding=utf8 -*-
當你在py檔案的第一行中,寫了這句話,並確實按照這個編碼儲存了文字的話,那麼這句話有以下幾個功能。
1. 使得詞法分析器能正常運作,對於註釋中的中文不報錯了。
2. 對於u”中文”這樣literal string能知道兩個引號中的內容是utf8編碼的,然後能正確轉換成unicode
3. “中文”對於這樣的literal string你會知道,這中間的內容是utf8編碼,然後就可以正確轉換成其它編碼或unicode了。
sys.getfilesystemencoding()
返回的字元編碼用於將Unicode檔名對映到底層作業系統使用的檔名。
對於Windows返回’mbcs’, 或對於Macintosh OSX返回’utf-8’。在UNIX系統上,編碼取決於區域設定並將返回區域引數CODESET的值。在使用預設編碼的系統上可能返回None。
-未完待續。。。