Python第五课——Python中encode和decode区别

所有的数据(文本、音频、视频等等)在计算机内部都是以二进制形式来表示的,所有的数据只可能是0或者1表示;比如我们需要存储字母a,那么我存入一个数字97(即在计算机中存入二进制(01100001),这个过程叫做编码(encode),而我们在读取数据的时候,当遇到97时,我们就让计算机显示字母a,这个过程叫做解码(decode)

最早的ASCII只能解决美国人的编码问题,无法将欧洲的文字表示出来;欧洲统一标准使用ISO-8859-1编码;但无法兼容中文,中国制定了GB2312编码,把中文编进去了;后来为了统一编码:Unicode(万国码)应运而生,Unicode把所有语言都统一到一套编码里
由此可知:
目前编码的方式主要有两种:ASCIIUnicode
那么看两者区别,ASCII编码是一个字节(8个bit为一个byte),而Unicode编码通常是两个字节(偏僻字符4字节,占内存多)
但是,如果文档内英文比较多,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算;所以又出现了把Unicode编码转化为“可变长编码”的UTF-8编码
UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节;那么可看出

ASCII编码实际上可以被看成是UTF-8编码的一部分

那么什么时候用utf-8编码什么时候用Unicode编码

对内存消耗要求高的,对CPU运算速度要求不高的场景下用utf-8
对速度要求特别高的,相对之下占用空间大小可以稍微妥协的场景下用Unicode编码
当我们的数据保存在硬盘的时候,当我们数据要在网络传输的时候,用得就是utf-8编码
当数据被加载到内存上时,在内存中的编码方式是Unicode

讨论Python编码问题前,先了解几个基本概念:
字节:计算机数据的表示,8位二进制。可以表示无符号整数:0-255;“字节流"表示"字节"组成的串
字符:英文字符"abc”,或者中文字符"你我他";字符本身不知道如何在计算机中保存;下文中,为避免使用"字符串"这个词,而用"文本"来表示
编码(encode):按照某种规则将"文本"转换为"字节流"
解码(decode):将"字节流"按照某种规则转换成"文本"

字符串在python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码

decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode(‘gb2312’),表示将gb2312编码的字符串str1转换成unicode编码----注:经常报错,要先知道其之前的编码
encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode(‘gb2312’),表示将unicode编码的字符串str2转换成gb2312编码

def code():
    s = '中文'
    print(s)  # 中文

    str1 = s.encode('gbk')
    print(str1, type(str1))  # b'\xd6\xd0\xce\xc4' 

    str2 = str1.decode('gbk')
    print(str2, type(str2))  # 中文 
    print(isinstance(str2, str))  # True

    str3 = s.encode('utf-8')
    print(str3, type(str3))  # b'\xe4\xb8\xad\xe6\x96\x87' 

    str4 = str3.decode('utf-8')
    print(str4, type(str4))  # 中文 


if __name__ == '__main__':
    code()

针对以上解码时不知道之前字符串如何编码的,解码报错情况我们可用chardet包去解决这个问题

import chardet

def code():
    str1 = "牛b"
    s = str1.encode('utf-8')
    print(s, type(s))  # b'\xe7\x89\x9b' 
    print(chardet.detect(s))  # {'encoding': 'Windows-1252', 'confidence': 0.73, 'language': ''}

    str2 = s.decode('Windows-1252')
    print(str2)  # 牛b  解码是错的,这是因为编码方式的继承性问题,留做大家讨论

if __name__=='__main__':
    code()

如上:
在python中,我们print(‘xxx’)是以Unicode编码的;其实总结之后可以说:python中的str是以Unicode编码的(注意,既然我们能看到str,说明这个python文件已经被打开了,即已经加载到内存上),如果要在网络上传输,或者保存到磁盘上,就得转换为utf-8编码方式;因为UTF-8省内存

默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串
默认指定源码文件指定不同的编码:

# -*- coding: cp-1252 -*-

上述定义允许在源文件中使用 Windows-1252 字符集中的字符编码,对应适合语言为保加利亚语、白罗斯语、马其顿语、俄语、塞尔维亚语。

a = '我出生中国,母语是chinese'
print(a, type(a))  # 我出生中国,母语是chinese 
"""如上,可见str的编码方式为Unicode,我们可以看懂 
    下面我将此进行ascii编码;此时输出报错UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-8: ordinal not in range(128)
"""
# b = a.encode('ascii')
# print(b, type(b))

c = 'I like nba'
print(c.encode('ascii'))  # b'I like nba'
print(c.encode('utf-8'))
"""如上输出带b,表明是以ASCII码编码的;当然也可用uft-8"""

附:
ISO-8859-1:是单字节编码,向下兼容ASCII,是许多欧洲国家使用的编码标准
Unicode:由国际组织标准制定,作为一种国际语言编码标准
UTF-8/UTF-16:”等则是对Unicode进行了编码,是其一种实现方式;UTF-8是一种变长的编码方式,它以8位为码元,用1-6个码元对Unicode进行编码,对英文字符使用单字节编码,对中文编码用三个字节来编码
GB2312:是国家制定的汉字编码标准,使用双字节进行编码,共收入6763个汉字和682个非汉字图形字符;GBK即对国标编码的扩展,在GB2312的基础上进行扩展形成的,使用双字节编码方式,共收入21003个汉字,从而大大满足了汉字使用的需要

# # 默认编码长度
str1 = "学习python"
print(str1, len(str1))
print(str1)
# utf-8 编码一个汉字3个字节长度
str2 = str1.encode('utf-8')
print(str2, len(str2))

学习python 8
学习python
b'\xe5\xad\xa6\xe4\xb9\xa0python' 12

你可能感兴趣的:(自动化测试,python)