完全搞清楚python字符編碼

 

在討論python編碼以前,我先了解了幾種編碼的由來。html

1、編碼類型

一、ascci碼

ascci碼由美國人發明,用1個字節(byte)存儲英文和字符,前期用了128個,後來新加了其餘歐洲國家的符號,128~255這一段。
256個字符,基本上就是鍵盤上的全部字符。python

二、unicode

2個byte,65535。由於後來發現還有其餘國家的語言,而256個字符太少。mysql

三、utf-8

UTF-8是Unicode的實現方式之一。
UTF-8最大的一個特色,就是它是一種變長的編碼方式。它可使用1~4個字節表示一個符號,根據不一樣的符號而變化字節長度。
UTF-8的編碼規則很簡單,只有二條:linux

  • 對於單字節的符號,字節的第一位設爲0,後面7位爲這個符號的unicode碼。所以對於英語字母,UTF-8編碼和ASCII碼是相同的。
  • 對於n字節的符號(n>1),第一個字節的前n位都設爲1,第n+1位設爲0,後面字節的前兩位一概設爲10。剩下的沒有說起的二進制位,所有爲這個符號的unicode碼。

下表總結了編碼規則,字母x表示可用編碼的位。sql


Unicode符號範圍         |       UTF-8編碼方式
(十六進制)                    |       (二進制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxxwindows

 

四、GBK

GBK全稱《漢字內碼擴展規範》(GBK即「國標)就是國家制定的標準。bash

其實GBK在就是將每一個漢字對應一個數字編碼,http://www.mytju.com/classCode/tools/encode_gb2312.asp 這個網址能夠查看到具體的編碼對應關係:服務器

好比:中國  二字,對應的各類編碼以下。工具

 

 

2、爲何要轉碼?

在python程序運行過程當中,若是遇到編碼不一致(就好像中國人和美國人在一塊兒,若是語言不通的話,就沒法溝通。),就須要進行轉碼。至關於須要有一個翻譯。測試

在運行Python程序的過程當中,會涉及到三個方面的編碼:

  1. Python程序文件自己的編碼(test.py文件的編碼)--自身文件

  2. Python程序運行時環境的編碼(好比securecrt,相似mysql客戶端鏈接時的編碼)--客戶端
  3. Python程序讀取外部文件的編碼(引用外部文件的編碼)--外部文件

下面對於以上三種狀況爲何須要轉碼分別進行說明:

狀況一(自身文件編碼問題)

python2默認編碼爲ascii,若是咱們寫的代碼裏面有非ascii字符,好比中文字符,py程序就會不認識。

就至關於兩我的都用普通話在溝通,其中某一我的忽然蹦出一句家鄉話,另一我的忽然就懵逼了,一樣,python也懵逼了。

記得剛開始接觸python時,就碰到了經典錯誤,而後網上各類找資料,後來照着網上前輩們的設置,也沒有深究其原理。

經典錯誤範例:

#!/usr/bin/env python

print '你好 大鳥'

運行時會報錯:

SyntaxError: Non-ASCII character '\xe4' in file t.py on line 4, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

錯誤緣由:python2默認的編碼爲ascii,python3默認編碼爲utf-8,而文件裏面包含了非ASCII字符,因此他確定不認識,就報錯了。

能夠經過sys模塊查看默認編碼:

>>> sys.getdefaultencoding()
'ascii'

怎麼解決?

針對狀況一解決方法:(目的都是將默認編碼修改爲utf-8,這樣,程序既能夠認識ascii,又能夠認識utf-8了)

解決方法一:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
解決方法二:
#coding:utf8
解決方法三:
#-*- coding:utf-8 -*-

  

 

狀況二(客戶端編碼問題) 

咱們在使用mysql時,若是客戶端設置爲latin,而服務端爲utf-8,查詢內容有中文時,就會出現亂碼。一樣,咱們在使用python時,secureCRT也是客戶端,服務端就是咱們鏈接的服務器。

範例:

一、客戶端設置secureCRT編碼爲UTF-8

 

二、服務端測試

 

三、設置客戶端爲非utf-8時,就會出現亂碼

 

結果以下:

並且從步驟2中也能夠看出,python自動識別變量a='中國test'爲utf-8的編碼,若是客戶端(secureCRT)和服務端(python)編碼不一致時,就會出現亂碼。

狀況二解決辦法:設置客戶端的編碼格式和服務端一致!

 

狀況三:讀取外部文件時,出現亂碼

比較典型的就是:當咱們從windows上編輯一個文件,上傳到linux上時,會驚奇的發現^M符號。這個就是由於windows和linux的回車換行符不一致致使的,此時若是是python文件時,python也會報錯。

 

咱們在linux先查看時會有特殊符號:

這時,若是咱們須要去掉^M,須要使用dos2unix工具轉換一下,去掉windows上的格式。

 

3、編碼怎麼轉換

unicode爲橋樑,utf-8和gbk互轉須要通過unicode這個翻譯,否則他們兩者是沒法直接溝通。

 

操做範例:

一、查看默認編碼,python遇到中文字符,會識別他是utf-8編碼,chardet模塊能夠識別編碼格式,可是也不是100%,下面他識別出myname爲utf-8的機率爲75%。

二、將utf-8轉爲unicode編碼

utf-8轉爲unicode編碼是,須要指定他自己是什麼格式的編碼,相似於加密。查看myname_unicode變量時,發現他是unicode編碼格式了。

三、將unicode編碼轉爲utf-8

具體轉換操做以下:

 

 例子:

>>> a=u'中國'  #unicode編碼格式的字符串
>>> a_utf8=a.encode('utf-8')  #將unicode轉成utf-8編碼格式
>>> a_utf8
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> a_unicode=a_utf8.decode('utf-8') #從utf8編碼格式轉回unicode編碼格式
>>> a_unicode
u'\u4e2d\u56fd'
>>> a
u'\u4e2d\u56fd'
>>>
>>> b_gbk=a_unicode.encode('gbk')  #將上面unicode格式的轉成gbk編碼格式
>>> b_gbk
'\xd6\xd0\xb9\xfa'
>>> b_unicode=b_gbk.decode('gbk') #轉回unicode編碼格式
>>> b_unicode   #最後發現,a_unicode、b_unicode和原始的unicode編碼的a都相等。
u'\u4e2d\u56fd'
>>> a_unicode
u'\u4e2d\u56fd'
>>> a
u'\u4e2d\u56fd'
>>> 

 

a.encode(* *):將a 編碼 爲 * *編碼格式的字符串或unicode對象

a.decode(* *):將a 解碼 爲 unicode編碼格式的字符串或unicode對象

 另外:

Python將字符串格式的unicode編碼轉換成unicode編碼,如:\u53eb\u6211,須要轉換成中文時有兩種方式

1.使用eval:

eval("u"+"\'"+unicodestr+"\'")

2.使用decode:

str1 = '\u4f60\u597d'  
print str1.decode('unicode_escape')  
你好 

unicodestr.decode('unicode_escape')  # 將轉義字符\u讀取出來

4、參考文獻和文件索引 

一、漢字對應表:http://www.chi2ko.com/tool/CJK.htm

二、阮一峯的網站

相關文章
相關標籤/搜索