
俗話說:“知己知彼方能百戰不殆”。要想了解字元編碼,咱們還得從計算機編碼說起!
* ASCII*
話說,發明計算機的美國人沒有想到計算機會在這短短幾十年内普遍全球,且英文字元的個數十分有限,大小寫字母,數字0 到9,标點符号,以及在美式英語中使用的特殊控制字元加起來也就百來個。而在計算機中一個位元組相當于8個比特位,8個比特位就可以表示256(2的8次方)個字元,ASCII碼規定用1個位元組存儲一個字元,簡直妥妥的!
擴充字元集
然而計算機在普及到其他國家時,他們發現有很多他們的字母裡有許多是ASCII裡沒有的,他們決定采用 127号之後的空位來表示這些新的字母、符号,還加入了很多畫表格時需要用下到的橫線、豎線、交叉等形狀,一直把序号編到了最後一個狀态255。從128 到255這一頁的字元集便是擴充字元集
GB2312
時代在進步,計算機普及到咱們中國來啦!但在普及的過程中我們面臨的最大問題,不是買不買得起而是字元編碼。因為華夏文明,博大精深,源遠流長。常見的漢字就有成千上萬個,這已經大大超過ASCII碼所能存儲的範圍。于是我們制定了GB2312,不客氣地把ASCII碼127号之後的奇異符号們直接取消掉, 規定:一個小于127的字元的意義與原來相同,但兩個大于127的字元連在一起時,就表示一個漢字,GB2312編碼裡,我們還把數學符号、羅馬希臘的字母、日文的假名們都編進去了,連在 ASCII 裡本來就有的數字、标點、字母都統統重新編了兩個位元組長的編碼,這就是常說的”全角”字元,而原來在127号以下的那些就叫”半角”字元了。基本滿足了漢字的計算機處理需要
GBK
雖然GB2312所收錄的漢字已經覆寫中國大陸99.75%的使用頻率。但是并不是100%鴨!對于一些罕見的字和繁體字,GB2312還是無法處理的鴨!于是在GB2312的基礎上建立了叫GBK的編碼,不僅收錄了27484個漢字,同時還收錄了蒙文,藏文等主要的少數名族文字。同樣GBK也相容了ASCII編碼,對于英文字元用1個位元組來表示,漢字用倆個位元組
Unicode
你可以想得到的是,全世界有上百種語言,日本把日文編到Shift_JIS裡,南韓把韓文編到Euc-kr裡,各國有各國的标準,就會不可避免地出現沖突,結果就是,在多語言混合的文本中,顯示出來會有亂碼。是以,Unicode應運而生。Unicode把所有語言都統一到一套編碼裡,這樣就不會再有亂碼問題了。Unicode标準也在不斷發展,但最常用的是用兩個位元組表示一個字元(如果要用到非常偏僻的字元,就需要4個位元組)。現代作業系統和大多數程式設計語言都直接支援Unicode。
utf-8
雖然unicode的出現使得亂碼問題從此消失了。但是如果你寫的文本基本上全部是英文的話,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不劃算。本着節約的精神,又出現了把Unicode編碼轉化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字元根據不同的數字大小編碼成1-6個位元組,常用的英文字母被編碼成1個位元組,漢字通常是3個位元組,隻有很生僻的字元才會被編碼成4-6個位元組。如果你要傳輸的文本包含大量英文字元,用UTF-8編碼就能節省空間
那些年的編碼知識已上齊!不知各位看官是否看得很懵逼?懵逼,那就多看幾遍!
接下來咱們該上大菜啦
python2
1,字元串的兩大陣營:str和unicode
在python2.7中,有兩種“字元串”類型,分别是str 與 unicode,他們有同一個基類basestring。str是plain string,其實應該稱之為位元組串,因為是每一個位元組換一個機關長度。而unicode就是unicode string,這才是真正的字元串,一個字元(可能多個位元組)算一個機關長度。
python2.7中,unicode類型需要在文本之間加u表示。
從上可以得出以下結論:第一s,c的類型是不一樣的;第二,同一個漢字,不同的類型其長度也是不一樣的,對于unicode類型的執行個體,其長度一定是字元的個數,而對于str類型的執行個體,其長度是字元對應的位元組數目。
2,str與unicode的轉換
unicode.encode--->str(編碼)
str.decode---->unicode(解碼)
3,指明的編碼名稱不對,抛出的報錯還是熟悉的“配方”,熟悉的顔色!
我們來好好“觀賞”圖中 UnicodeEncodeError ,它分别展示了使用的編碼方式, “codec” 即編碼、解碼器,導緻問題的字元的位置。從中我們可以得出錯誤原因:“ascii 隻能表示 0-127個 字元中的一個。然而我們的 字元串早已經超出了範圍。”
偷偷告訴你哦其實我們可以通過設定encode 或者 decode 的第二個參數來指明codec 不能夠處理資料的時候會發生的情況。通常第二參數的預設值是 “strict” ,就像剛才一樣,會抛出一個異常。再者我們可以輸入“replace” ,它意味着,失敗時将會傳回一個标準的替代字元。或者輸入”ignore” ,它會直接将不能解碼的 bytes 丢掉。
python3
1,字元串的倆大陣營:byte和str
跟 Python 2 類似,Python 3 也有兩種類型,一個是 Unicode,一個是 byte 碼。但是它們有不同的命名。python3你從普通文本轉換成 “str” 類型後存儲的是一個 unicode, “bytes” 類型存儲的是 byte 串。你也可以通過一個 b 字首來制造 byte 串。即py3中的str=py2中的unicode,py3中 的byte=py2中的str
2.byte與str的轉換
在python3中str都是unicode,是以對于str隻有encode(),沒有decode(),而byte是由str使用encode()生成的,是以byte可以通過decode()即解碼,得到真正的内容。