python2字元編碼問題總結
阿新 • • 發佈:2018-12-29
來源自我的部落格
- 各種編碼轉化由unicode物件中轉,編碼即是將unicode物件轉換成各類編碼字串,解碼即是將種類編碼字串轉換成unicode物件
- gbk編碼與gb2312編碼結果一致,gb2312只包括簡體漢字,gbk(國標擴充套件)包括所有簡體繁體漢字以及日文假名
- 定義unicode物件
s = u"哈哈" #定義s為unicode物件,type unicode
s #u'\u54c8\u54c8
print s #哈哈
- 定義gbk字串
s_gbk = "哈哈" #定義為gbk字串,type str
s_gbk #'\xb9\xfe\xb9\xfe'
print s_gbk #哈哈
- 定義utf-8字串
s_utf8 = s.encode('utf-8') #定義為utf-8字串,type str
s_utf8 #'\xe5\x93\x88\xe5\x93\x88'
print s_utf8 #鍝堝搱
unicode物件與其他編碼字串互轉
1. unicode物件轉成其他編碼字串
s2gbk = s.encode('gbk') #定義為gbk字串,type str
s2gbk #'\xb9\xfe\xb9\xfe'
print s2gbk #哈哈
s2utf8 = s.encode('utf-8') #定義為utf8字串,type str
s2utf8 # '\xe5\x93\x88\xe5\x93\x88'
print s2utf8 #鍝堝搱
2. 其他編碼字串轉成unicode物件
gbk2s = s_gbk.decode('gbk') #定義為unicode物件,type unicode
gbk2s #u'\u54c8\u54c8
print gbk2s #哈哈
utf82s = s_utf8.decode('utf-8') #定義為unicode物件,type unicode
utf82s #u'\u54c8\u54c8
print utf82s #哈哈
- 其他編碼字串間互轉
1. gbk編碼字串轉成utf-8編碼字串
gbk2utf8 = s_gbk.decode('gbk').encode('utf-8') #定義為utf字串,type str
gbk2utf8 #'\xe5\x93\x88\xe5\x93\x88'
print gbk2utf8 #鍝堝搱
2. utf-8編碼字串轉成gbk編碼字串
utf82gbk = s_utf8.decode('utf-8').encode('gbk') #定義為gbk字串,type str
utf82gbk #'\xb9\xfe\xb9\xfe'
print utf82gbk #哈哈
- 其他編碼字串間直接互轉(即未解碼直接轉碼)
gbk2utf8 = s_gbk.encode('utf-8') #可能會拋異常UnicodeDecodeError
如果丟擲這個異常,原因在於gbk編碼的字串直接編碼成utf-8編碼的字串時python會將其先解碼成unicode再編碼成utf-8,其中解碼這一步使用的是預設編碼。如果預設編碼不是gbk就不能正常解碼,所以會拋異常。
解決辦法有二:
- 手動解碼後再編碼,缺點在於程式中多處用到的話不方便修改
gbk2utf8 = s_gbk.decode('gbk').encode('utf-8')
- 修改預設編碼
import sys
reload(sys) #reload的原因是python2.5後初始化後會刪除下面那句
sys.setdefaultencoding('gbk') #設定預設編碼為gbk
- print輸出utf-8編碼字串原因,當print的為unicode物件時會直接處理輸出,當print的為編碼字串時,會解碼成unicode物件輸出。預設的解碼方式使用的是gb2312,而utf-8編碼字串不能用gb2312解碼,所以輸出亂碼,可以手動解碼後輸出
print s_utf8.decode('utf-8')
- 檔案編碼宣告與檔案編碼儲存型別
- 如果程式碼中出現了中文,想要正常顯示的話建議在程式碼第一行或第二行新增語句
#-*- coding:utf-8 -*-
這個的作用是宣告程式碼中將會出現中文,並且會將檔案中的字串使用此編碼轉換成unicode物件
- 檔案儲存時選擇的編碼型別決定了檔案中出現的中文將被儲存成什麼型別的編碼字串
例如:
#-*- coding:utf-8 -*-
s = u'哈哈'
將此檔案儲存成utf-8編碼。
首先獲取’哈哈’的編碼,由檔案編碼決定,為’\xe5\x93\x88\xe5\x93\x88’(哈哈的utf-8編碼形式)
然後轉成unicode物件,由編碼宣告決定,按utf-8解碼成unicode物件
- unicode物件儲存的字串與unicode物件互相轉化
- unicode物件轉成其儲存內容的字串
s = u"哈哈" #定義s為unicode物件,type unicode,len=2
s #u'\u54c8\u54c8
print s #哈哈
s_str = s.encode('unicode-escape') #定義為str,type str,len=12
s_str #'\\u54c8\\u54c8' #多的兩個\為轉義
print s_str #\u54c8\u54c8
- 儲存unicode物件內容的字串轉成unicode物件
s_t = '\u54c8\u54c8' #定義為str,type str,len=12
s_t #'\\u54c8\\u54c8' #多的兩個\為轉義
print s_t #\u54c8\u54c8
s_unicode = s_t.decode('unicode-escape') #此時s_unicode與s完全一樣,type unicode,len=2
s_unicode #u'\u54c8\u54c8
print s_unicode #哈哈