Python2和Python3中字符串編碼問題詳解

本文參考:

https://www.cnblogs.com/saolv/p/8158159.html

https://blog.csdn.net/mycar001/article/details/78364357

首先說明:Python2和Python3的默認字符串編碼是不一樣的!

首先需要知道什麼是Unicode,Unicode是一種編碼,類似於ASCII、UTF8,而Python以Unicode編碼爲轉換中介,進行字符串的轉碼。

瞭解一下什麼是編碼,解碼:

字符需要有效傳輸,所以需要將字符編碼爲二進制的字節序列,解碼就是從二進制序列,按照指定的規則,恢復出原始的內容。

字符→編碼encode→字節序列

字節序列→解碼decode→字符

 

瞭解Python中的編碼和解碼:

Python中解碼就是把某種編碼格式的“內容”解碼成Unicode字符串,編碼就是將Unicode編碼成具有某種編碼格式的“內容”,Python中encode和decode的默認參數(也可以自己指定編碼)是指定的編碼(Python2爲ASCII,Python3爲utf8),與你模塊的編碼,編譯環境的全局編碼,第一行指定的編碼都沒有關係!

Python2中:

str類型(utf8等編碼)字符串→解碼(decode)→Unicode類型(Unicode編碼)字符串

Unicode類型(Unicode編碼)字符串→編碼(encode)→str類型(utf8等編碼)字符串

Python3中:

str類型(Unicode編碼)字符串→編碼(encode)→bytes類型字節序列

bytes類型字節序列→解碼(decode)→str類型(Unicode編碼)字符串

Python3中的str類型就等於Python2中的Unicode類型!!!

 

Python2中的字符串有兩個類型,分別爲str和unicode,接下來看兩者區別

看一段代碼:

# coding:utf-8
str1 = "嚴"
print type(str1)
print str1
print len(str1)

str2 = u"嚴"
print type(str2)
print str2
print len(str2)


運行結果:
<type 'str'>
嚴
3
<type 'unicode'>
嚴
1

下面解釋每一行代碼

Python2中你定義字符串的時候,字符串的類型是str,也就是具有某種編碼格式的字符串(默認爲ASCII)

第一行代碼是聲明本模塊的編碼格式,因爲默認爲ASCII,當不寫這一行的時候,字符串是沒辦法輸入漢字的,寫上這一行

以後,str1就是以utf8編碼的類型爲str的字符串,輸出的是它本身,長度爲3(可以理解這個3,不知道怎麼解釋,utf8一個漢字三個字節)。

str2是一個unicode類型的字符串,輸出也爲它本身,長度爲1(1個Unicode)

 

再看一段代碼:

# coding:utf8
str1 = "嚴"  #utf8的str類型的字符串
print type(str1)
print str1
print len(str1)

str2=str1.decode("utf8")  #參數必須與第一行的聲明相同,解碼爲unicode類型的字符串
print type(str2)
print str2
print len(str2)

str3=str2.encode("utf8")  #unicode字符串編碼爲utf8的str類型的字符串
print type(str3)
print str3
print len(str3)

str4=str2.encode("gbk")  #unicode字符串編碼爲gbk的str類型的字符串
print type(str4)
print str4
print len(str4)

運行結果:
<type 'str'>
嚴
3
<type 'unicode'>
嚴
1
<type 'str'>
嚴
3
<type 'str'>
��
2

str1爲utf8(第一行決定的)編碼的str類型的字符串。第二段代碼decode將其解碼爲unicode類型的字符串str2.

Python2中的encode和decode函數默認爲ASCII編碼,可以自己寫參數指定。

第三段代碼,unicode類型的str2用utf8編碼格式編碼爲str類型的字符串str3,同理,第四段代碼, unicode類型的str2用gbk編碼格式編碼爲str類型的字符串str4。當中文以utf8編碼的時候佔3個字節,以gbk編碼的時候佔2個字節。至於第四段輸出亂碼問題我感覺是控制檯的編碼是utf8的原因。

需要知道的是str類型和unicode類型的字符串輸出到控制檯都是可見的字符串,不是字節序列(bytes)。

 

 

接下來看Python3:

Python3中:字符串有str類型(Unicode編碼)和bytes類型(字節序列)兩種

str類型(Unicode編碼)字符串→編碼(encode)→bytes類型字節序列

bytes類型字節序列→解碼(decode)→str類型(Unicode編碼)字符串

Python3中的str類型就等於Python2中的Unicode類型!!!

看兩者的區別:

 

 

看段代碼:

str1 = "我是abc"
print(type(str1))
print(str1)
print(len(str1))

str2 = bytes("我是abc", encoding="utf8")
print(type(str2))
print(str2)
print(len(str2))

運行結果:
<class 'str'>
我是abc
5
<class 'bytes'>
b'\xe6\x88\x91\xe6\x98\xafabc'
9

 注意:Python3的字符串默認爲Unicode編碼的字符串(str類型),不需要加上Python2代碼中的(# coding:utf8)

str1爲str類型的(Unicode編碼)的字符串,可以直接顯示,長度爲5。

str2爲bytes類型的(必須指定編碼格式)字節序列,輸出時看到的不是字符串,是b開頭的字節序列,長度爲9,utf8中一個漢字三個字節。

注意:Python2中str類型和Unicode類型輸出都是可見的字符串,Python3中str類型(Unicode編碼)爲可見字符串,bytes類型爲字節序列,輸出看不懂。

再看一段代碼:

str1 = "我是abc"
print(type(str1))
print(str1)
print(len(str1))

str2 = str1.encode()  # 默認爲utf8,等效於encode("utf8")
print(type(str2))
print(str2)
print(len(str2))

str3 = str2.decode()  # 默認爲utf8,等效於decode("utf8")
print(type(str3))
print(str3)
print(len(str3))

str4 = str1.encode("gbk")
print(type(str4))
print(str4)
print(len(str4))

str5 = str4.decode("gbk")  # 參數需要與上面相同
print(type(str5))
print(str5)
print(len(str5))

str6 = str4.decode("utf16",errors="ignore")  #以不同方式解碼的話就會報錯或者亂碼,由參數決定
print(str6)


執行結果:
<class 'str'>
我是abc
5
<class 'bytes'>
b'\xe6\x88\x91\xe6\x98\xafabc'
9
<class 'str'>
我是abc
5
<class 'bytes'>
b'\xce\xd2\xca\xc7abc'
7
<class 'str'>
我是abc
5
틎쟊扡

str1的類型爲str(Unicode編碼),str2爲str1用默認編碼格式(utf8)編碼以後形成的bytes類型的字節序列,str3爲str2解碼後的str類型的字符串,str4和str5分別於str2和str3相同,只是編碼不同,編碼不同也導致了長度不同,,str6位當解碼方式不同的時候的亂碼,會報錯,可以用參數忽略錯誤。

 

先寫到這,回頭想起來什麼再來不錯,有什麼不對的地方,希望大家可以提出。

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