Python2 & Python3 编码格式

目录

一些编码知识

python2 编码格式

python3 编码格式

Python2 & Python3 差异


一些编码知识

编码

指从字符到二进制数据的映射过程

 

GB2312

收录了大部分中文字符(6763个汉字),兼容 ASCII

 

GBK

在 GB2312 基础上收录了藏文、蒙文、维吾尔文等主要的少数民族文字

英文字符用 1 个字节,汉字用 2 个字节。

 

Unicode

计算机怎么知道一个 2 字节的 Unicode 字符是表示一个 2 字节的字符,还是两个 1 字节的字符呢?

Unicode 只是规定如何编码,并没有规定如何传输、保存编码。UTF-9、UTF-16 是 Unicode 编码的实现方式。

 

UTF-8

是一种变长的编码,可以用 1 - 4 字节,英文字符用 1 个字节。

对于多个(n)字节的字符,第一个字节的前 n 位都设为 1,第 n + 1 位设为 0,后面字节的前两位都设为 10,剩下的二进制位全部用该字符的 Unicode 码填充。

以汉字“好”为例,“好”的 Unicode 编码是 597D,对应的区间是 0000 0800 - 0000 FFFF,所以用 UTF-8 表示时需要 3 个字节。

597D 的二进制表示是:101 1001 0111 1101,按照以上规则填充到 1110xxxx 10xxxxxx 10xxxxxx 中,就是 11100101 10100101 10111101,转为十六进制:E5A5BD。

 

以下是常见的汉字字符集编码:

GB2312编码:1981年5月1日发布的简体中文汉字编码国家标准。GB2312对汉字采用双字节编码,收录7445个图形字符,其中包括6763个汉字。

 

BIG5编码:台湾地区繁体中文标准字符集,采用双字节编码,共收录13053个中文字,1984年实施。

 

GBK编码:1995年12月发布的汉字编码国家标准,是对GB2312编码的扩充,对汉字采用双字节编码。GBK字符集共收录21003个汉字,包含国家标准GB13000-1中的全部中日韩汉字,和BIG5编码中的所有汉字。

 

GB18030编码:2000年3月17日发布的汉字编码国家标准,是对GBK编码的扩充,覆盖中文、日文、朝鲜语和中国少数民族文字,其中收录27484个汉字。GB18030字符集采用单字节、双字节和四字节三种方式对字符编码。兼容GBK和GB2312字符集。

 

UNICODE编码:国际标准字符集,它将世界各种语言的每个字符定义一个唯一的编码,以满足跨语言、跨平台的文本信息转换。

 

 

 

  • 获取默认编码的方法

Python IDLE:

>>> import sys

>>> sys.getdefaultencoding()

'ascii'

 

Windows 10:

C:\Users\fhj>chcp

活动代码页: 936

 

Linux:

fhj@baron:~$ locale

LANG=en_US.UTF-8

LANGUAGE=en_US

 

 

 

python2 编码格式

  • 字符串对象

和字符串相关的数据类型(字符串对象):str、unicode。

str 和 unicode 都是 basestring 的子类。basestring是抽象类,所以不能被调用和实例化,但是可以用来判断一个对象是否为str或unicode的实例:

isinstance(obj, basestring)等价于isinstance(obj, (str, unicode))

Windows下:

>>> s = "好"
>>> type(s)
<type 'str'>
>>> s
'\xba\xc3'

>>> s = u"好"
>>> type(s)
<type 'unicode'>
>>> s
u'\u597d'

Linux下:

>>> s = "好"
>>> type(s)
<type 'str'>
>>> s
'\xe5\xa5\xbd'

>>> s = u"好"
>>> type(s)
<type 'unicode'>
>>> s
u'\u597d'

u"好" 表示"好"的 unicode 编码,不同平台下 unicode 类型的字符串存的都是 unicode 编码,是一样的;

而 str 类型的字符串编码格式是 GBK、UTF-8 还是其它格式,和操作系统的默认编码有关。如上,在 Windows 下是 '\xba\xc3',这是 GBK 格式,在 Linux 下,是 '\xe5\xa5\xbd',这是 UTF-8。

 

  • str 和 unicode 的相互转换

>>> s = "好"
>>> u = u"好"
>>> s.decode("gbk")
u'\u597d'
>>> s.decode("gb2312")
u'\u597d'

>>> u.encode("utf-8")
'\xe5\xa5\xbd'
>>>
>>> u.encode("gbk")
'\xba\xc3'

 

 

  • str() 和 unicode()

str(u) 等价于 u.encode("ascii"),将 unicode 字符串转换成 ascii 字符串。

unicode(s) 等价于 s.decode("ascii"),将 ascii 字符串转换成 unicode 字符串。

所以,str(u)、unicode(s) 都不能对包含非 ascii 字符的字符串进行转换,会报类似如下的错误:

>>> u = u"好"
>>> s = "好"
>>> str(u)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# UnicodeEncodeError: 'ascii' codec can't encode character u'\u597d' in position 0: ordinal not in range(128)
>>> unicode(s)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# UnicodeDecodeError: 'ascii' codec can't decode byte 0xba in position 0: ordinal not in range(128)

 

指定正确的编码就可以解决这个问题:

1、用 u.encode("gbk") 代替 str(u)

2、用 s.decode("gbk") 代替 unicode(s)

>>> u.encode('gbk')
'\xba\xc3'
>>> s.decode('gbk')
u'\u597d'

 

  • 一个 str 字符串对象,其中存的是 unicode 形式的字符串,要将这个 str 转成真正的 unicode 字符串对象,可使用 s.decode('unicode-escape'):
>>> st = 'id\u6211\u662f001'
>>> u = st.decode('unicode-escape')
>>> type(u)
<type 'unicode'>
>>> u
u'id\u6211\u662f001'
>>>
>>> g = u.encode('gbk')
>>> type(g)
<type 'str'>
>>> g
'id\xce\xd2\xca\xc7001'

 

 

 

 

 

python3 编码格式

  • str

Python3 中:没有 unicode 类型,str 的编码格式为 unicode,等于 Python2 的unicode 类型。

>>> s = "中文"
>>> type(s)
<class 'str'>
>>> s
'中文'

 

  • bytes

bytes 表示二进制字节序列,对 str 进行编码后得到 bytes;反之,对 bytes 解码后得到 str。

>>> b = b"0123aa"
>>> type(b)
<class 'bytes'>
>>> b2 = b"\xff\xabd\x38\x12"
>>> b2
b'\xff\xabd8\x12'
>>> len(b2)
5

 

  • python2 与 python3 字节与字符的对应关系

python2

python3

表现

转换方法

作用

str

bytes

字节

decode

存储

unicode

str

字符

encode

显示

 

  • str 和 bytes 的相互转换

https://img.jbzj.com/file_images/article/201704/2017422192524292.jpg?2017322192535

str转 bytes(encode):

>>> s.encode('gbk')
b'\xd6\xd0\xce\xc4'
>>> type(s.encode('gbk'))
<class 'bytes'>
>>> s.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> s.encode()
b'\xe4\xb8\xad\xe6\x96\x87'

 

bytes 转 str(decode):

>>> b.decode()
'0123aa'
>>> b.decode('gbk')
'0123aa'

 

>>> s = "中文"
>>> s
'中文'
>>> s.encode("gbk")
b'\xd6\xd0\xce\xc4'
>>> 
>>> b'\xd6\xd0\xce\xc4'.decode('gbk')
'中文'

 

  • str() 和 bytes()

str(b, encoding=’gbk’):把 bytes 转成 str,同时指定转换前 bytes 的编码格式为 gbk,等同于b.decode(‘gbk’)。

>>> b = b'\xd6\xd0\xce\xc4'
>>> str(b, encoding='gbk')
'中文'

>>> s = "中文"
>>> bytes(s, encoding='utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> bytes(s, encoding='gbk')
b'\xd6\xd0\xce\xc4'

bytes(s, encoding=’gbk’):把 str 转成 gbk 编码的 bytes,等同于s.encode(‘gbk’)。

 

 

 

 

Python2 & Python3 差异

  • 解释器对代码的处理

Python2 默认编码是 ASCII,必须在文件头声明 coding 为 utf-8 或者 gbk 后才能有中文字符,Python2 解释器以文件头声明的编码去解释代码,并加载到内存中,也就是说内存中的编码格式和文件编码格式是一样的。所以当 coding 为 utf-8 时,中文打印出来是乱码,为 gbk 时打印出来不会变乱码。

Python3 默认编码是 unicode,Python3 解释器会以文件头声明的编码去解释代码,在加载到内存中之前会先转成 unicode,所以当 coding 为 utf-8 时,打印中文也不会乱码。

 

  • bytes 类型

Python 2 将 str 处理为原生的 bytes 类型,而不是 unicode,可以认为 str 等于 bytes:

>>> isinstance('abc123', str)
True
>>> isinstance('abc123', bytes)
True

Python 3 所有的 str 均是 unicode 类型。

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值