python編碼的那些事
字串編碼在python裡是經常會遇到的問題,特別是寫檔案或是網路傳輸呼叫某些函式的時候.
現在來看看python中的unicode編碼和utf-8編碼
字串編碼的歷史
-
計算機只能處理數字,文字轉換為數字才能處理. 計算機中8個bit作為一個位元組,所以一個位元組能表示最大的數字為255
-
計算機是美國人發明的,一個位元組就可以表示所有的英文字元了,所以ACSII(一個位元組)編碼就成為美國人的標準編碼
-
但是中文裡遠遠不止255個漢字,這時用ASCII來處理中文是明顯不夠用的,所以我國制定了GB2312編碼,用兩個位元組表示一個漢字.
GB2312還把ASCII包含進去.同理,別的國家為了解決自己國家的編碼問題也都發展了一套位元組的編碼,這樣標準就越來越多.
如果一篇文章出現多種語言混合顯示就一定會出現亂碼.
-
這裡unicode出現了,unicode把所有的語言統一到一套編碼裡.
-
看一下ASCII編碼和unicode編碼:
字母A用ASCII編碼十進位制是65,二進位制是0100 00001
漢字”中”已經超出了ASCII編碼的範圍,用unicode編碼是20013,二進位制是0100 1110 0010 1101
A用unicode編碼只需要前面補0,二進位制是00000000 0100 0001 -
亂碼問題解決了,但是如果一段內容全是英文,unicode編碼比ASCII需要多一倍的儲存空間,浪費很多硬碟容量.同時傳輸時也需要多浪費很多頻寬.
-
“utf-8″會把英文變成一個位元組,漢字3個位元組.特別生僻的變成4到6個位元組.如果傳輸的英文,就把英文輪換成unicode編碼格式.
python儲存檔案和讀取檔案時編碼的關係
儲存檔案時,把unicode編碼轉換成utf-8編碼格式
讀取檔案時,把utf-8編碼轉換成unicode編碼格式
分別在windows系統和linux系統中測試python2和python3的編碼區別
在windows系統的python2版本
中
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)] on win32
>>> str1="hello" # 因為str1和str2都是英文,所以atr1和str2不管是unicode編碼還是ASCII格式
>>> str2=u"hello" # encode成utf-8編碼時都不會出現錯誤
>>> str1.encode("utf-8")
`hello`
>>> str2.encode("utf-8")
`hello`
>>> type(str1)
<type `str`>
>>> type(str2)
<type `unicode`>
>>> str3="我用python" # python中的字串在記憶體中是用unicode來編碼的
>>> str4=u"我用python" # str3在windows系統中儲存成GBK編碼
>>> str3.encode("utf-8") # str3在呼叫encode方法之前必須轉換為unicode編碼
Traceback (most recent call last): # 此時str3應該先decode成為unicode編碼,然後再encode成utf-8編碼
File "<input>", line 1, in <module>
UnicodeDecodeError: `ascii` codec can`t decode byte 0xe6 in position 0: ordinal not in range(128)
>>> str3.decode("utf-8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:Python27libencodingsutf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: `utf8` codec can`t decode byte 0xce in position 0: invalid c
ontinuation byte
>>> str3.decode(`gbk`)
u`u6211u7528python`
>>> str3.decode("utf-8").encode("utf-8")
`xe6x88x91xe7x94xa8python`
>>> str4.encode("utf-8")
`xe6x88x91xe7x94xa8python`
>>> type(str3)
<type `str`>
>>> type(str4)
<type `unicode`>
>>> import sys
>>> sys.getdefaultencoding()
`ascii`
在windows系統的python3版本
中
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> str1="hello" # python3中所有的字串都是unicode編碼
>>> str2=u"hello"
>>> str1.encode("utf-8")
b`hello`
>>> str2.encode("utf-8")
b`hello`
>>> str3="我用python"
>>> str3.encode("utf-8")
b`xe6x88x91xe7x94xa8python`
>>> str4=u"我用python"
>>> str4.encode("utf-8")
b`xe6x88x91xe7x94xa8python`
>>> import sys
>>> sys.getdefaultencoding()
`utf-8`
在linux系統的python2版本
中
Python 2.7.5 (default, Nov 6 2016, 00:28:07)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> str1="我用python"
>>> str1.encode("utf-8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: `ascii` codec can`t decode byte 0xe6 in position 0: ordinal not in range(128)
>>> str1.decode("gbk")
u`u93b4u6220u6564python`
>>> str1.decode(`utf-8`) # linux系統中python2會把字串儲存成utf-8編碼,那為什麼不能直接encode呢?
u`u6211u7528python` # 字串在encode之前應該保證是一個unicode編碼格式,字串在encode之前
# 會呼叫decode方法把字串轉換成unicode編碼,然後才能encode
>>> str1.decode("utf-8").encode("utf-8") # str1字串中含有中文,直接encode成utf-8編碼會出現錯誤
`xe6x88x91xe7x94xa8python`
>>> str1.decode("gbk").encode("utf-8")
`xe9x8exb4xe6x88xa0xe6x95xa4python`
>>> str2=u"我用python"
>>> str2.encode("utf-8")
`xe6x88x91xe7x94xa8python`
>>> type(str1)
<type `str`>
>>> type(str2)
<type `unicode`>
>>> import sys
>>> sys.getdefaultencoding()
`ascii`
在linux系統的python3版本
中
Python 3.6.3 (default, Nov 7 2017, 20:33:25)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> str1="我用python" # python3中所有的字串都是unicode編碼
>>> str2=u"我用python"
>>> str1.encode("utf-8")
b`xe6x88x91xe7x94xa8python`
>>> str2.encode("utf-8")
b`xe6x88x91xe7x94xa8python`
>>> import sys
>>> sys.getdefaultencoding()
`utf-8`
不管是windows系統還是linux系統,python2版本中預設使用ASCII編碼
,python3版本預設使用utf-8編碼
相關文章
- 字元編碼那些事兒字元
- Java程式碼的編譯與反編譯那些事兒Java編譯
- XSS與字元編碼的那些事兒 ---科普文字元
- jad反編譯工具的那些事編譯
- python之協程的那些事Python
- WiFi密碼破解那些事WiFi密碼
- 關於爛程式碼的那些事(下)
- 關於爛程式碼的那些事(上)
- 關於爛程式碼的那些事(中)
- 程式碼重構那些事兒
- 關於密碼字典那些事密碼
- 關於元件文件從編寫到生成的那些事元件
- Synchronized的那些事synchronized
- webassembly 的那些事Web
- ViewPager的那些事Viewpager
- 《星球大戰》與Python之間的那些事Python
- Java 混淆那些事(六):Android 混淆的那些瑣事JavaAndroid
- iOS CollectionView 的那些事iOSView
- 微服務的那些事微服務
- webpack的那些事兒Web
- HTTP 2.0 的那些事HTTP
- HTTP 2.0的那些事HTTP
- Ubuntu的那些事兒Ubuntu
- 讓人疑惑的Java程式碼 – Java那些事兒Java
- 讓人疑惑的Java程式碼 - Java那些事兒Java
- 關於是託管程式碼的那些事兒
- Python和單元測試那些事兒Python
- rem那些事REM
- JavaScript那些事JavaScript
- mysql那些事MySql
- GCD那些事GC
- 原始碼篇:Handler那些事(萬字長文)原始碼
- 移動端彈窗輸入密碼的那些事密碼
- 關於MySQL密碼你應該知道的那些事MySql密碼
- 關於 MySQL 密碼你應該知道的那些事MySql密碼
- IT風雲15年的那些人那些事
- 敏捷開發的那些事敏捷
- https的那些事兒HTTP