python與字符編碼問題
用python2的小伙伴肯定會遇到字符編碼的問題。下面對編碼問題做個簡單的總結(jié),希望對各位有些幫助。
故事零:編碼的定義
我們從“SOS“(國際通用求助信號)開始,它的摩斯密碼的編碼是:
“…---…”,想一下為什么選用S、O、S來作為求救信號?因為它簡單,容易辨別且不容易發(fā)錯呀!
那么,字符編碼就是:
´給定一系列字符,對每個字符賦予一個數(shù)值,用數(shù)值來代表對應的字符,這一數(shù)值就是字符的編碼。例如,我們給字符'A'賦予數(shù)值0x41,則0x41就是字符'A'的編碼。字符編碼是字符的表現(xiàn)、儲存方式。
字符編碼需要處理兩件事:
(1)規(guī)定一個字符集中的字符由多少個字節(jié)表示;
(2)制定該字符集的字符編碼表,即該字符集中每個字符對應的(二進制)值。
字符集:´給定一系列字符并賦予對應的編碼后,所有這些字符和編碼對組成的集合就是字符集。´比如,給定字符列表為{'A','B'}時,{'A'=>0x41,‘B'=>0x42}就是一個字符集。
常見字符集有:
ASCII
GB2312
GBK
GB18030
Big5
Unicode
一張圖總結(jié):
故事一:Python2與Python3的字符串類型?
python2中的字符串有str和unicode類型,而python3中字符串只有unicode類型。比如 ‘你好'是str字符串,而 u'你好'則是unicode字符串。
故事二:decode()和encode()傻傻分不清?
decode() 是將str字符串轉(zhuǎn)化為unicode字符串;encode() 是將unicode字符串轉(zhuǎn)化為str字符串。所以要做一些編碼的轉(zhuǎn)換通常是以unicode作為中間編碼做轉(zhuǎn)換。如name.decode(“GB2312”)表示將GB2312編碼的字符串name轉(zhuǎn)換成unicode編碼,name.encode(“GB2312”)表示將unicode字符串name轉(zhuǎn)換成GB2312編碼。
故事三:UnicodeEncodeError: ‘a(chǎn)scii' codec can't encode character?
我們先看看兩張圖,是不是很煩?
下面我們看個例子:
當用u'字符串'申明這個字符串變量時就指明了該字符串是使用unicode字符編碼。當要將unicode字符串轉(zhuǎn)換為str字符串或者寫入文件時,python2默認使用ASCII 碼保存數(shù)據(jù),而ASCII 碼無法識別大于128 的字符,于是報了上面的錯誤。
附ASCII碼表:
故事四:unicode是什么?
unicode可以看做一個終極的字符編碼方法,它給出了地球上常用字符的二進制映射,而且所有的二進制字符串唯一地表示一個字符。但是,unicode只給出了字符和二進制串的對應關(guān)系,并沒有給出存儲形式。而不同字符所占用的存儲空間可能不同,比如ASCII 在unicode中只占用了一個字節(jié)即可,而常用漢字在unicode中需要占用兩個字節(jié),還有一些羅馬字符可能需要三個或以上字節(jié)。如果直接存儲的話可能導致無法分割字符串,也無法正確解碼出字符。
故事五:UTF-8橫空出世?
互聯(lián)網(wǎng)的普及,強烈要求出現(xiàn)一種統(tǒng)一的編碼方式。這時候UTF-8 出場。UTF-8 是unicode在計算機中的一種實現(xiàn)方式。UTF-8是一種變長編碼,每個字符占1-4 個字節(jié)。UTF-8 將字節(jié)分為數(shù)值位和標識位,數(shù)值位真正保存字符編碼數(shù)值,標識位表示這個字節(jié)是屬于哪個字符的、或者該字符占多少個字節(jié)。UTF-8 編碼方法:
單字節(jié),首位為標識位0;多字節(jié)字符首字節(jié)標志位1··10開頭,字符占多少字節(jié)則有多少1,其他字節(jié)標識位10開頭;
§ 單字節(jié)字符: 0xxxxxxx (以0 開頭標志位,數(shù)值位用x 表示)
§ 雙字節(jié)字符: 110xxxxx 10xxxxxx
§ 三字節(jié)字符: 1110xxxx 10xxxxxx 10xxxxxx
§ 四字節(jié)字符: 11110xxx 10xxxxxx 10xxxxxx10xxxxxx
unicode變?yōu)閁TF-8 編碼非常簡單,unicode二進制按照從低到高,填充UTF-8的數(shù)值位,除去那些不真正表示數(shù)值的標識位(字節(jié)開頭的0,10,110,1110和11110),順序也是由低到高。以漢字“你”為例,可見它的unicode編碼為“4f60”(01001111 01100000)。
從“你”的unicode值范圍可以看到需要三個字節(jié),接著從低位字節(jié)向高位字節(jié)填充得到“你”的UTF-8 編碼(高位沒有填充完則用0補充)。
可以看到將UTF-8 用于標記位(紅色)的位去掉,合并可以得到原始的unicode碼。
故事六:"unicode-escape"與"unicode-unescape"
“\u”是表示unicode的轉(zhuǎn)義字符,用\uxxxx這種方式表示unicode字符就是”unicode-escape”方式。說人話:´一句話:xxx.decode(“unicode-escape”)相當于把xxx解碼成unicode類型并返回。
而用”%uxxxx”的方式表示unicode字符,這種方式就是”unicode-unescape”,常用于javascript。
番外故事七:讀了那么多年書,你真的了解“全半角”?
全角---指一個字符占用兩個標準字符位置。
半角---指一字符占用一個標準的字符位置。
引申:寫程序時雙引號、冒號、小括號等為啥如此糾結(jié)?
--我國專家在制定GB2312字符集時,ASCII里本來就有的數(shù)字、標點、字母都統(tǒng)統(tǒng)重新編了兩個字節(jié)長的編碼。
是不是腦殼疼呀,想想我國程序員因為中英文切換犧牲了多少寶貴時間啊,啊嘿!
總結(jié)
以上所述是小編給大家介紹的python與字符編碼問題 ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
相關(guān)文章
python使用pika庫調(diào)用rabbitmq交換機模式詳解
這篇文章主要介紹了python使用pika庫調(diào)用rabbitmq交換機模式詳解,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-08-08Python?matplotlib的spines模塊實例詳解
作為程序員,經(jīng)常需要進行繪圖,下面這篇文章主要給大家介紹了關(guān)于Python?matplotlib的spines模塊的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-08-08Python中利用函數(shù)裝飾器實現(xiàn)備忘功能
這篇文章主要介紹了Python中利用函數(shù)裝飾器實現(xiàn)備忘功能,同時還降到了利用裝飾器來檢查函數(shù)的遞歸、確保參數(shù)傳遞的正確,需要的朋友可以參考下2015-03-03教你使用Sublime text3搭建Python開發(fā)環(huán)境及常用插件安裝另分享Sublime text3最新激活注冊碼
這篇文章主要介紹了使用Sublime text 3搭建Python開發(fā)環(huán)境及常用插件安裝,并提供了最新Sublime text 3激活注冊碼需要的朋友可以參考下2020-11-11