18-python中bytes和 str的关系 以及编码encode,解码decode相关的知识

1. python当中采取的是哪种编码?

import sys
print(sys.getdefaultencoding())

程序运行的结果:

utf-8

2. str 字符串

1. 原始字符串

Python 字符串中的反斜杠\有着特殊的作用,就是转义字符,例如上面提到的\'\"

转义字符有时候会带来一些麻烦,例如我要表示一个包含 Windows 路径D:\Program Files\Python 3.8\python.exe这样的字符串,在 Python 程序中直接这样写肯定是不行的,不管是普通字符串还是长字符串。

因为\的特殊性,我们需要对字符串中的每个\都进行转义,也就是写成D:\\Program Files\\Python 3.8\\python.exe这种形式才行。

这种写法需要特别谨慎,稍有疏忽就会出错。为了解决转义字符的问题,Python 支持原始字符串。在原始字符串中,\不会被当作转义字符,所有的内容都保持 原汁原味 的样子。

在普通字符串或者长字符串的开头加上r前缀,就变成了原始字符串,具体格式为:

str1 = r'原始字符串内容'
str2 = r"""原始字符串内容"""

示例代码:

rstr = r'D:\Program Files\Python 3.8\python.exe'
print(rstr)

程序运行的结果:

D:\Program Files\Python 3.8\python.exe

3. bytes

Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分。

文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示。Python 3不会以任意隐式的方式混用str和bytes,你不能拼接字符串和字节流,也无法在字节流里搜索字符串(反之亦然),也不能将字符串传入参数为字节流的函数(反之亦然)

bytes是一种比特流,它的存在形式是01010001110这种。我们无论是在写代码,还是阅读文章的过程中,肯定不会有人直接阅读这种比特流,它必须有一个编码方式,使得它变成有意义的比特流,而不是一堆晦涩难懂的01组合。因为编码方式的不同,对这个比特流的解读也会不同,对实际使用造成了很大的困扰。下面让我们看看Python是如何处理这一系列编码问题的:

s = "中文"
print(s)
print(type(s))

b = bytes(s, encoding='utf-8')
print(b)

print(type(b))

程序运行的结果:

中文
<class 'str'>
b'\xe4\xb8\xad\xe6\x96\x87'
<class 'bytes'>

从例子可以看出,s是个字符串类型。Python有个内置函数bytes()可以将字符串str类型转换成bytes类型,b实际上是一串01的组合,但为了在ide环境中让我们相对直观的观察,它被表现成了b'\xe4\xb8\xad\xe6\x96\x87'这种形式,开头的b表示这是一个bytes类型。\xe4是十六进制的表示方式,它占用1个字节的长度,因此"中文"被编码成utf-8后,我们可以数得出一共用了6个字节,每个汉字占用3个,这印证了上面的论述。在使用内置函数bytes()的时候,必须明确encoding的参数,不可省略。

我们都知道,字符串类str里有一个encode()方法,它是从字符串向比特流的编码过程。而bytes类型恰好有个decode()方法,它是从比特流向字符串解码的过程。除此之外,我们查看Python源码会发现bytes和str拥有几乎一模一样的方法列表,最大的区别就是encode和decode。

从实质上来说,字符串在磁盘上的保存形式也是01的组合,也需要编码解码。

  1. 在将字符串存入磁盘和从磁盘读取字符串的过程中,Python自动地帮你完成了编码和解码的工作,你不需要关心它的过程。

  2. 使用bytes类型,实质上是告诉Python,不需要它帮你自动地完成编码和解码的工作,而是用户自己手动进行,并指定编码格式。

  3. Python已经严格区分了bytes和str两种数据类型,你不能在需要bytes类型参数的时候使用str参数,反之亦然。这点在读写磁盘文件时容易碰到。

在bytes和str的互相转换过程中,实际就是编码解码的过程,必须显式地指定编码格式。

>>> b
b'\xe4\xb8\xad\xe6\x96\x87'
>>> type(b)
<class 'bytes'>
>>> s1 = str(b)
>>> s1
"b'\\xe4\\xb8\\xad\\xe6\\x96\\x87'"
>>> type(s1)
<class 'str'>
>>> s1 = str(b, encoding='utf-8')
>>> s1
'中文'
>>> type(s1)
<class 'str'>

4. encode() 和decode()

1. encode()

encode() 方法为字符串类型(str)提供的方法,用于将 str 类型转换成 bytes 类型,这个过程也称为“编码”。
encode() 方法的语法格式如下:

str.encode([encoding="utf-8"][,errors="strict"])

注意,格式中用 [] 括起来的参数为可选参数,也就是说,在使用此方法时,可以使用 [] 中的参数,也可以不使用。

该方法各个参数的含义如表 1 所示。
在这里插入图片描述
注意,使用 encode() 方法对原字符串进行编码,不会直接修改原字符串,如果想修改原字符串,需要重新赋值。

例如 将 str 类型字符串"中文"转换成 bytes 类型。

>>> str = '中文'
>>> str
'中文'
>>> str.encode()
b'\xe4\xb8\xad\xe6\x96\x87'
>>>

此方式默认采用 UTF-8 编码,也可以手动指定其它编码格式,例如:

>>> str
'中文'
>>> str.encode('GBK')
b'\xd6\xd0\xce\xc4'
>>>

2. decode()

和 encode() 方法正好相反,decode() 方法用于将 bytes 类型的二进制数据转换为 str 类型,这个过程也称为“解码”。

decode() 方法的语法格式如下:

bytes.decode([encoding="utf-8"][,errors="strict"])

该方法中各参数的含义如表 2 所示。
在这里插入图片描述

例子

>>> str
'中文'
>>> str.encode()
b'\xe4\xb8\xad\xe6\x96\x87'
>>> bytes =  str.encode()
>>> bytes
b'\xe4\xb8\xad\xe6\x96\x87'
>>> bytes.decode()
'中文'
>>>

注意,如果编码时采用的不是默认的 UTF-8 编码,则解码时要选择和编码时一样的格式,否则会抛出异常,例如:

>>> bytes = str.encode('GBK')
>>> bytes
b'\xd6\xd0\xce\xc4'
>>> bytes.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6 in position 0: invalid continuation byte
>>>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值