【工程類】【Python】一文搞懂Python字符編碼問題

Python的字符編碼很是讓人頭疼,動不動就出現encode和decode ERROR的這些問題,,鑑於此,準備好好研究一番字符編碼的問題,整理成文章。後續也會根據所學繼續加入自己的理解。由於本人並非大神,如有講錯之處也請各位大神指出。

1、一些專有名詞解釋

字節
字節是計算機存儲數據的基本單元,由8個bit組成。1024個字節就是1KB。
字符
字符是信息的基本單位,比如一個字母A,一個漢字‘好’,一個標點符號等,都可以稱之爲字符。
字符集
顧名思義,字符集就是字符的集合,比如全部的英文字母及其標點符號組成的集合(ASCII),比如全部中文字符及相應的標點符號組成的集合(GBK)
字符碼 字符編碼
字符碼就是一個字符在字符集中所對應的編碼,由於計算機只能識別ibt,所以對於一個字符來說,可以將這個字符表示爲計算機可以識別的編碼。比如字母‘a’,在ASCII中代表的字符碼是97,其字符編碼是0110 0001
編碼 解碼
編碼的過程就是將字符轉化爲字節流。
解碼的過程就是講字節流轉化爲字符。

2、字符編碼的歷史

如果想要研究一個東西,那麼我們就要知道這個東西的起源及歷史原因。

2.1 ASCII編碼

我們都知道,計算機這玩意最早是美國的,所以美國針對自己的語言設立了一套編碼,這就是ASCII編碼。由於英文字母有限,加上各種特殊字符之類的,總共湊了127個,所以完全可以用一個字節來表示,下圖是ASCII表的表示。
在這裏插入圖片描述

2.2 MBCS編碼

但是隨着計算機的發展,更多國家接入了計算機,所以傳統的ASCII碼不能很好地表示不同國家的語言了。每個國家便推出了自己國家的編碼規則,在兼容ASCII碼的同時,又加入了自己的編碼規則,由於ASCII編碼是單字節,不能滿足更多語言,所以一般會用雙字節編碼。
注意:MBCS不是一種編碼,而是所有雙字節編碼的總稱

2.2.1 GBK

咱們中國人在1981年也頒佈了自己的中文編碼,GB2312,GB2312 編碼共收錄了6763個漢字,同時他還兼容 ASCII,GB 2312的出現,基本滿足了漢字的計算機處理需要,它所收錄的漢字已經覆蓋中國大陸99.75%的使用頻率,不過 GB2312 還是不能100%滿足中國漢字的需求,對一些罕見的字和繁體字 GB2312 沒法處理,後來就在GB2312的基礎上創建了一種叫 GBK 的編碼,GBK 不僅收錄了27484個漢字,同時還收錄了藏文、蒙文、維吾爾文等主要的少數民族文字。同樣 GBK 也是兼容 ASCII 編碼的,對於英文字符用1個字節來表示,漢字用兩個字節來標識。
在這裏插入圖片描述
可以看到,GBK和GB2312對於‘好’這個字的編碼相同,且佔兩個字節。

2.3 unicode

雖然各個國家開發了自己國家的編碼極大的解決了ASCII編碼單字節的侷限性,但是當各個國家之間的編碼進行交互的時候又出現了問題,不同規則的編碼在編碼解碼的過程中很容易出現亂碼,且不容易維護。所以,unicode應運而生。
unicode是一種字符編碼的統一,大家想出了一種策略,我們就用兩個字節來表示,這就是UCS-2,不過後來大家發現256*256的空間同樣不夠了,就用4個字節來代替,這就是UCS-4。
unicode這種編碼格式其實就是一種映射關係,將每一個字符映射到唯一的一個位上。

2.4 UTF-8

Unicode可以有效的解決了編碼問題,不過老美們用了一段時間就不幹了,我們自己的語言用一個字節就可以了,爲啥還要用2個或者4個字節,太浪費空間了,所以老美們想出來一種字符編碼UTF-8。那UTF-8是咋回事呢?這個是一種邊長的字符編碼。
對於一串序列來說首先判斷第一位如果是0,則是單字節,11則是雙字節,以此類推,其中後一個字節前兩位均用10來表示。
在這裏插入圖片描述

3、Python2.X中的字符編碼問題

終於到我們的重頭戲了。
首先可以用一張圖來一目瞭然的瞭解Python中的字符編碼問題
在這裏插入圖片描述
解釋一下:在Python中,str和unicode都繼承basestring,str我們可以理解爲一個字節數組,這點非常重要,比如用utf-8編碼爲XXX,在str中就是[‘XXX’],如果說用GBK編碼爲AAA,則在str中就是[‘AAA’].

3.1 如何用encode和decode進行str和unicode類型間的轉換

在這裏插入圖片描述

4、Python執行流程解析

4.1執行流程

step1 根據文件編碼將文件提交給解釋器
step2 根據編碼聲明對文件進行逐行處理
step3 對於有打印到屏幕上的中文字符按sys.stdout.encoding進行編碼
文件編碼:文件是什麼編碼就是什麼編碼
編碼聲明:

#-*-coding:utf-8

打印編碼:一般是根據操作系統進行設置

4.2舉例說明

case1:文件編碼GBK,系統編碼GBK

print "你好"

報錯:SyntaxError: Non-ASCII character '\xd5' in file /Users/leishuo/PycharmProjects/first/a.py on line 4, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
原因:step1:首先會根據文件編碼將"你好"編譯成“’\xc4\xe3\xba\xc3’”
step2:由於沒有文件聲明,所以會用默認ACSII碼進行處理,由於ASCII無法處理“’\xc4\xe3\xba\xc3’”,所以報錯。
case2:文件編碼GBK,系統編碼GBK

#-*-coding:utf-8
print "你好"

可能會報錯
原因:由於有些高級編譯器會根據文件聲明自動將文件編碼轉化爲文件聲明編碼。
如果進行轉化:step1 將文件轉化爲utf-8編碼。此時“你好”編碼爲"\xe4\xbd\xa0\xe5\xa5\xbd"
step2 根據文件聲明進行處理。
step3 根據系統編碼輸出結果。

參考:

https://www.jianshu.com/p/53bb448fe85b
http://www.cnblogs.com/xsmhero/archive/2012/11/20/2778857.html
http://blog.sina.com.cn/s/blog_9f447dfd0102wp55.html##1
http://sa.sogou.com/sgsearch/sgs_tc_news.php?req=itzlnVR0ZmG7epVZiQ_9gYkn8bX_OL3UUkhQTWY37VAIQccfkBS8PHtXJWcymRa_&user_type=1
https://www.jb51.net/article/26543.htm
https://blog.csdn.net/ggggiqnypgjg/article/details/53271541

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章