带你看懂python2与python3在字符编码方面的区别

从python2更新到python3,相信每个人都遇到过爬取网页编码错乱,编码转码混淆等问题,在这里,笔者详细说明一下python2与python3之间的字符编码问题,也是个人在使用过程中的一些总结。

1. 什么是字符编码: 计算机里所有数据,本质都是二进制表示。

先带大家来看下什么是编码

这里用的是python3环境,python3环境默认字符串的字符类型是str,默认编码类型是Unicode,字符类型和编码类型是不一样的。在上图chr是找到数字对应的ASCII表里面的字符

编码表:将计算机里的二进制数据,通过编码表对应,转换为人类可以看懂的字符。

所以97 ASCII  ‘a’ ASCII就是编码类型,常用编码类型还有Unicode、utf-8、gbk,他们的发展历程是这样的

最早的计算机是美国人发明的,最开始设计编码表的时候,只考虑的美国的语言习惯(数据、字母和普通字符)0~127, ASCII 美国标准信息交换码

后来计算机开始普及全球,欧洲 Latin-1、 中国简体中文 GB2312、繁体中文 Big5、日本Shift_JIS,0~127不够用了,各个国家开始指定自己的编码表(在ASCII表基础上进行扩展,所以前127个都是一样的) 导致各个国家的编码不统一,文化交流不方便,文本内容传输做编码转换很麻烦。

于是国标组织指定了一个大一统的编码表:Unicode 万国码(给世界上每个字符,单独指定了一个二进制,再通过Unicode编码表转换)

 Unicode里每个字符占用4个字节(不够4个字节,前面补0),所以Unicode浪费空间。

        'a' == 00000000 00000000 00000000 01100001

 于是在Unicode基础上做了升级,UTF-8(可变长的Unicode),可以根据字符类型来指定字节空间(尽可能减少空间占用)

 在UTF-8里,一个字母1个字节,一个汉字3个字节 ; 在GBK里,一个字母1个字节,一个汉字2个字节(在简体中文处理GBK优于UTF-8)

UTF-8 也是当前世界上最流行的编码表处理方案,所有的Linux终端默认编码是UTF-8, 90%的网页都是UTF-8,简体中文的Windows终端默认编码是 GBK,也称为 CP936 (code page 936)

现在再来说python2与python3编码的区别

  Python3 类型 和 编码:

        str 类型字符串 是 Unicode编码

        bytes 类型字符串 是 非Unicode(GBK、utf-8、jpg、mp4、mp3)

    Python2 类型 和 编码:

        str 类型字符串 是 非Unicode编码(GBK、utf-8、jpg、mp4、mp3)

        unicode 类型字符串 是 Unicode编码

那么问题就来了,如果遇到字符串编码不一致,如何转为同一个编码统一处理?

解决办法:任何操作系统、任何编程语言、任何编码字符串,都可以和Unicode互相转换。

在python2与3中需要用到encode编码与decode解码

在python3中str类型字符串‘unicode_str’编码是unicode编码,这个是万能编码,可以通过utf-8编码为utf-8编码的bytes类型

反过来,bytes类型通过utf-8解码还成为原来的字符串。

同样也可以用GBK编码

到了这里可能就有疑惑了,为什么通过GBK编码再用UTF-8解码还原后是一样的,是因为输入的是英文,而英文的编码都是一样的,所以重点来了

将中文使用utf-8编码再用GBK解码

到这里是否就清楚了一些,为什么在爬取网页下载到本地的时候会出现乱码,是因为网页可能采用GBK编码,而python3对下载的网页默认使用UTF-8解码

那么python2的环境看看,值得注意Python2的终端创建字符串,Windows 是 GBK,  Linux 是 UTF-8, 为 str 类型(Python2的 str 是 非Unicode)我用的是mac,是UTF-8编码,而Python2默认解释器编码为ascii,所以来看看

是不是有点奇怪,为什么在python2输入字符串再使用utf-8编码会报错,而解码不报错。再来看看

到了这里是否能明白了,因为所有的编码解码出问题基本都是非英文字符。而几大编码是包含关系,unicode最大,可以使用其他编码,而其他编码使用都可以解码为unicode类型,再看

在python2中str类型默认编码类型为ascii,但是中文不在ascii码范围之内,因为在终端输入的编码类型不为ascii,根据终端环境为GBK或者utf-8,也是非unicode,所有非unicode编码均可以解码为unicode编码,因为unicode编码包含了所有编码。所有的编码与解码。会根据当前环境的不同而产生不同的效果,具体都可以自己多测试测试就可以明白,但是需要注意一点,在写入文件的时候一定要注意编码统一,如果追加的编码类型不一样会导致整个文件的编码错误,除非手动切分再重新编码才能还原。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值