在討論python編碼以前,我先了解了幾種編碼的由來。html
ascci碼由美國人發明,用1個字節(byte)存儲英文和字符,前期用了128個,後來新加了其餘歐洲國家的符號,128~255這一段。
256個字符,基本上就是鍵盤上的全部字符。python
2個byte,65535。由於後來發現還有其餘國家的語言,而256個字符太少。mysql
UTF-8是Unicode的實現方式之一。
UTF-8最大的一個特色,就是它是一種變長的編碼方式。它可使用1~4個字節表示一個符號,根據不一樣的符號而變化字節長度。
UTF-8的編碼規則很簡單,只有二條:linux
下表總結了編碼規則,字母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即「國標)就是國家制定的標準。bash
其實GBK在就是將每一個漢字對應一個數字編碼,http://www.mytju.com/classCode/tools/encode_gb2312.asp 這個網址能夠查看到具體的編碼對應關係:服務器
好比:中國 二字,對應的各類編碼以下。工具
在python程序運行過程當中,若是遇到編碼不一致(就好像中國人和美國人在一塊兒,若是語言不通的話,就沒法溝通。),就須要進行轉碼。至關於須要有一個翻譯。測試
在運行Python程序的過程當中,會涉及到三個方面的編碼:
Python程序文件自己的編碼(test.py文件的編碼)--自身文件
下面對於以上三種狀況爲何須要轉碼分別進行說明:
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上的格式。
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讀取出來
一、漢字對應表:http://www.chi2ko.com/tool/CJK.htm
二、阮一峯的網站