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位当解码方式不同的时候的乱码,会报错,可以用参数忽略错误。

 

先写到这,回头想起来什么再来不错,有什么不对的地方,希望大家可以提出。

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