從python2,python3編碼問題引伸出的通用編碼原理解釋

來源:互聯網
上載者:User

標籤:ash   height   簡單   解釋   開頭   聲明   mysql資料庫   就會   數字   

今天使用python2編碼時遇到這樣一條異常UnicodeDecodeError: ‘ascii’ code can’t decode byte 0xef

發現是編碼問題,但是平常在python3中幾乎沒有遇到過,所以特意查了資料,原來python3和python2對於字串的理解不一樣,在python3中,字串預設unicode編碼

一.解釋python2和python3文本處理方式

在Python3當中,文本字串類型(使用Unicode資料存放區)被命名為 str , 位元組字串類型被命名為 bytes 。一般情況下,執行個體化一個字串會得到一個 str 對象 :

如果你想得到bytes,那就在文本之前加上首碼 b , 或者 encode 一下。

所以,很顯然,str 對象有一個encode方法,bytes 對象有一個decode方法。

在Python3中的 str 對象在Python2中叫做 unicode , bytes 對象在Python2中叫做 str 

在python2中使用中文字串的方式是在頁首聲明# *--coding:utf-8--* 

 

二.常用編碼方式

順便在網上查了一下字元集和編碼方式的文檔,發現很多人都解釋的難以理解,所以這裡嘗試說清楚一下。這裡不解析字元集和編碼方式,統稱為編碼方式。

不論什麼編碼,在電腦中統一是按照二進位位元組形式儲存,一個位元組有8位

1.ASCII碼,總共有128個,用1個位元組的低7位來表示

2.ISO-8859-1,128個字元表示明顯不夠用,所以ISO組織又制訂了新的標準來擴充ASCII碼,它們是ISO-8859-1到ISO-8859-15,其中ISO-8859-1涵蓋了大部分西歐編碼,所以用的最多。ISO-8859-1也是單位元組編碼,總共表示256個字元,發現字元變成?時,一般是使用了ISO-8859-1編碼,規定不認識範圍內的使用3f表示的就是?

3.GB2312,雙位元組編碼,範圍為A1-F7,其中A1-A9是符號區,包含682個符號,B0-F7是漢字區,包含6763個漢字,漢字使用兩個位元組表示

4.GBK,用於擴充GB2312,編碼範圍8140~FEFE,總共有23940個碼位,使用GB2312編碼的漢字可以用GBK來解碼

5.UTF-16,所有字元都是用兩個位元組,兩個位元組為16bit,所以叫UTF-16,但是浪費空間.(同unicode)

6.UTF-8,每個編碼地區有不同的字碼長度,最長為三個位元組,編碼規則如下:

(1)如果一個位元組的第一位為0,那麼代表當前字元為單位元組字元,佔用一個位元組的空間。0之後的所有部分(7個bit)代表在Unicode中的序號。
(2)如果一個位元組以110開頭,那麼代表當前字元為雙位元組字元,佔用2個位元組的空間。110之後的所有部分(7個bit)代表在Unicode中的序號。且第二個位元組以10開頭
(3)如果一個位元組以1110開頭,那麼代表當前字元為三位元組字元,佔用2個位元組的空間。110之後的所有部分(7個bit)代表在Unicode中的序號。且第二、第三個位元組以10開頭
(4)如果一個位元組以10開頭,那麼代表當前位元組為多位元組字元的第二個位元組。10之後的所有部分(6個bit)代表在Unicode中的序號

具體每個位元組的特徵可見下表,其中x代表序號部分,把各個位元組中的所有x部分拼接在一起就組成了在Unicode字型檔中的序號

Byte 1 Byte 2 Byte3
0xxx xxxx    
110x xxxx 10xx xxxx  
1110 xxxx 10xx xxxx 10xx xxxx

我們分別看三個從一個位元組到三個位元組的UTF-8編碼例子:

實際字元 在Unicode字型檔序號的十六進位 在Unicode字型檔序號的二進位 UTF-8編碼後的二進位 UTF-8編碼後的十六進位
$ 0024 010 0100 0010 0100 24
¢ 00A2 000 1010 0010 1100 0010 1010 0010 C2 A2
€ 20AC 0010 0000 1010 1100 1110 0010 1000 0010 1010 1100 E2 82 AC

細心的讀者不難從以上的簡單介紹中得出以下規律:

  • 3個位元組的UTF-8十六進位編碼一定是以E開頭的
  • 2個位元組的UTF-8十六進位編碼一定是以C或D開頭的
  • 1個位元組的UTF-8十六進位編碼一定是以比8小的數字開頭的
三.常見問題處理之Emoji

所謂Emoji就是一種在Unicode位於\u1F601–\u1F64F區段的字元。這個顯然超過了目前常用的UTF-8字元集的編碼範圍\u0000–\uFFFF。Emoji表情隨著IOS的普及和的支援越來越常見。下面就是幾個常見的Emoji:

那麼Emoji字元表情會對我們平時的開發營運帶來什麼影響呢?最常見的問題就在於將他存入MySQL資料庫的時候。一般來說MySQL資料庫的預設字元集都會配置成UTF-8(三位元組),而utf8mb4在5.5以後才被支援,也很少會有DBA主動將系統預設字元集改成utf8mb4。那麼問題就來了,當我們把一個需要4位元組UTF-8編碼才能表示的字元存入資料庫的時候就會報錯:ERROR 1366: Incorrect string value: ‘\xF0\x9D\x8C\x86‘ for column 。 如果認真閱讀了上面的解釋,那麼這個報錯也就不難看懂了。我們試圖將一串Bytes插入到一列中,而這串Bytes的第一個位元組是\xF0意味著這是一個四位元組的UTF-8編碼。但是當MySQL表和列字元集配置為UTF-8的時候是無法儲存這樣的字元的,所以報了錯。

【附】手持兩把錕斤拷, 口中疾呼燙燙燙。 腳踏千朵屯屯屯, 笑看萬物鍩鍩鍩。

從python2,python3編碼問題引伸出的通用編碼原理解釋

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.