python str byte编码_python str与bytes编码解码

编码和解码

下面一张图搞懂编码、解码、编码表之间的关系。

7d567f114eca

编码解码

不难看出,它们是一种根据编码表进行翻译、映射的过程:

编码:str --> bytes

解码:bytes --> str

实际上,字符串类型只有encode()方法,没有decode()方法,而bytes类型只有decode()方法而没有encode()方法。

>>> set( dir(str) ) - set( dir(bytes) )

{'encode', ... , 'isidentifier', 'format'}

>>> set( dir(bytes) ) - set( dir(str) )

{'decode', 'hex', 'fromhex'}

二进制格式的数据也常称为裸数据(raw data),所以str数据经过编码后得到raw data,raw data解码后得到的str。

python中的编码、解码

上面说了,编码是将字符数据转换成字节数据(raw data),解码是将字节数据转换成字符数据。在Python中字符数据也就是字符串,即str类型,字节数据也就是bytes类型或bytearray类型。

编码时,可以使用字节类型的构造方法bytes()、bytearray()来构造字节,也可以使用str类型的encode()方法来转换。

解码时,可以使用str类型的构造方法str()来构造字符串,也可以使用bytes、bytearray()类型的decode()方法。

另外需要注意的是,编码和解码的过程中都需要指定编码表(字符集),默认采用的是utf-8字符集。

编码过程

例如,使用encode()的方式将str编码为bytes数据。

>>> str1 = "abcd"

>>> str2 = "我爱你"

# 默认编码

>>> str1.encode()

b'abcd'

>>> str2.encode()

b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'

# 显式指定使用utf-8进行编码

>>> str1.encode("utf-8")

b'abcd'

>>> str2.encode("utf-8")

b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'

# 使用utf-16编码

>>> str1.encode("utf-16")

b'\xff\xfea\x00b\x00c\x00d\x00'

>>> str2.encode("utf-16")

b'\xff\xfe\x11b1r`O'

# 使用gb2312编码

>>> str1.encode("gb2312")

b'abcd'

>>> str2.encode("gb2312")

b'\xce\xd2\xb0\xae\xc4\xe3'

# 使用gbk编码

>>> str1.encode("gbk")

b'abcd'

>>> str2.encode("gbk")

b'\xce\xd2\xb0\xae\xc4\xe3'

使用bytes()和bytearray()将str构造成bytes或bytearray数据,这两个方法都要求str->byte的过程中给定编码。

>>> bytes(str1,encoding="utf-8")

b'abcd'

>>> bytes(str1,encoding="utf-16")

b'\xff\xfea\x00b\x00c\x00d\x00'

>>> bytearray(str1,encoding="utf-8")

bytearray(b'abcd')

>>> bytearray(str2,encoding="utf-8")

bytearray(b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0')

实际上,bytes()、bytearray()这两个方法构造字节数据的时候还有点复杂,因为可以从多个数据源来构造,比如字符串、整数值、buffer。如何使用这两个方法构造字节数据,详细内容参考help(bytes)和help(bytearray)给出的说明,这里给几个简单示例。

构造bytes的方式:

# 构造空bytes对象

>>> bytes()

b''

# 使用str构造bytes序列,需要指定编码

>>> bytes("abcd",encoding="utf-8")

b'abcd'

# 使用int初始化5个字节的bytes序列

>>> bytes(5)

b'\x00\x00\x00\x00\x00'

# 使用可迭代的int序列构造字节序列

# int值必须为0-256以内的数

>>> bytes([65,66,67])

b'ABC'

# 使用bytes或buffer来构造bytes对象

>>> bytes(b'abcd')

b'abcd'

构造bytearray的方式:

# 构造空bytearray对象

>>> bytearray()

bytearray(b'')

# 使用bytes或buffer构造bytearray序列

>>> bytearray(b"abcd")

bytearray(b'abcd')

# 使用str构造bytearray序列,需要指定编码

>>> bytearray("abcd",encoding="utf-8")

bytearray(b'abcd')

# 使用int初始化5个字节的bytearray序列

>>> bytearray(5)

bytearray(b'\x00\x00\x00\x00\x00')

# 使用可迭代的int序列构造bytearray序列

# int值必须为0-256以内的数

>>> bytearray([65,66,67])

bytearray(b'ABC')

解码过程

解码是字节序列到str类型的转换。

例如,使用decode()方法进行解码"我"字,它的utf-8的编码对应为"\xe6\x88\x91":

>> b = b'\xe6\x88\x91'

# 采用默认字符集utf-8

>>> b.decode()

'我'

# 显式指定编码表

>>> b.decode("utf-8")

'我'

使用str()进行转换。

>>> str(b,"utf-8")

'我'

关于乱码

当编码、解码的过程使用了不同的(不兼容的)编码表时,就会出现乱码。所以,解决乱码的唯一方式是指定对应的编码表进行编码、解码。

例如,使用utf-8编码"我"字,得到一个bytes序列,然后使用gbk解码这个bytes序列。

>>> "我".encode().decode("gbk")

Traceback (most recent call last):

File "", line 1, in

UnicodeDecodeError: 'gbk' codec can't decode byte 0x91 in position 2: incomplete multibyte sequence

这里报错了,因为utf-8的字节序列里有gbk无法解码的字节。如果使用文本编辑器一样的工具去显化这个过程,得到的将是乱码字符。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 3中,我们需要理解编码解码的概念以及Unicode和bytes之间的转换。 Unicode是一种编码规范,它包括了世界上几乎所有字符的映射关系。它的目的是为了实现全球文字的统一编码,使得不同语言和符号都可以在计算机中表示和处理。 在Python 3中,字符串是使用Unicode编码表示的,这意味着字符串可以包含任意字符和符号。当我们在编写Python代码时,可以直接使用Unicode字符,不需要做额外的编码处理。 然而,计算机实际上是通过字节(byte)来存储和传输数据的,所以我们需要将Unicode字符转换为bytes类型才能进行存储和传输。 在Python 3中,我们可以使用encode()方法将Unicode字符串编码bytes。例如,可以使用UTF-8编码将Unicode字符串编码为字节,如:bytes_data = str_data.encode('utf-8')。 相反地,当我们从外部来源(如文件、网络)获取到bytes类型的数据时,我们需要将其解码为Unicode字符串才能进行处理。我们可以使用decode()方法将bytes解码为Unicode字符串。例如,可以使用UTF-8解码将字节解码为Unicode字符串,如:str_data = bytes_data.decode('utf-8')。 需要注意的是,编码解码时使用的编码名称必须与数据的实际编码一致,否则会导致乱码问题。 总而言之,Python 3中编码解码涉及将Unicode字符串转换为bytes以及将bytes解码为Unicode字符串的过程。通过使用encode()和decode()方法,我们可以在不同的编码方案之间进行转换,以满足不同的应用需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值