1. 主页
  2. Python基础到高级
  3. 字符串
  4. bytes

bytes

这一篇说的就是Python 2 和Python 3 最大的区别了

字符串与bytes

str是文本序列

bytes是字节序列

在Linux Python 3 中默认是使用utf-8的

编码的解释

  • 文本是有编码的(utf-8, gbk, GB18030等)
  • 字节没有编码这种说法
  • 文本的编码是指字符如何使用字节来表示

一、bytes

1. encode

小例子 1

>>> strings = '兰玉磊'
>>> print(type(strings))
<class 'str'>
>>> strings.encode()   将字符串编码为bytes
b'\xe5\x85\xb0\xe7\x8e\x89\xe7\xa3\x8a'   utf-8的一个字节序列

>>> '兰'.encode()
b'\xe5\x85\xb0'
>>> '玉'.encode()
b'\xe7\x8e\x89'
>>> '磊'.encode()
b'\xe7\xa3\x8a'
通过上面的小例子,我们可以看出,以'\'为分割符,每三组编码就代表着一个汉字

下例子 2

尝试将bytes转十进制和二进制

我们拿'兰'字的bytes数据来举例子
>>> 0xe5
229
>>> 0x85
133
>>> 0xb0
176
我们将 '\' 去掉,前面加上0,就可以将bytes转成十进制的数据

转成二进制的数据,就需要借助一个bin方法来实现了
>>> bin(0xe5)
'0b11100101'
>>> bin(0x85)
'0b10000101'
>>> bin(0xb0)
'0b10110000'
这样我们可以看到,我们将转换过的十进制数据转成了二进制的数据

从上面的例子中我们就可以看出。'兰'字在计算机中的表现方式了 11100101 10000101 10110000

2. decode

同样,encode可以将string变成bytes格式的数据,也有方法也可以将bytes数据变成string的

>>> strings = '兰玉磊'
>>> b = strings.encode()   将兰玉磊编码为bytes
>>> b
b'\xe5\x85\xb0\xe7\x8e\x89\xe7\xa3\x8a'
>>> b.decode()   将bytes转化为string
'兰玉磊' 

bytes的定义

bytes 是str通过encode转化得到的
通过 b 前缀来定义bytes
>>> b'\xe5\x85\xb0'
b'\xe5\x85\xb0'
>>> type(b)
<class 'bytes'>

bytes的操作,除了encode外,str操作都有对应bytes的版本,但是传入参数也必须是bytes

>>> b = b'\xe5\x85\xb0'
>>> b.find('兰')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not 'str'
这个bytes对应的是 '兰' 字,但是我们使用find方法查找的时候,会抛出异常
由此我们可以看出来,bytes的参数只能bytes类型的

>>> b = '兰玉磊'
>>> b = b.encode()
>>> b
b'\xe5\x85\xb0\xe7\x8e\x89\xe7\xa3\x8a'    
>>> b.find(b'\xe5')    由此我们可以看出bytes的操作是按照字节来的
0

bytes新增的几个操作

b.decode()   转化成str
b.hex()   转化为16进制

为什么在Python3中要将bytes和str区分出来呢,我想如果用过Python的人,或多或少的都会遇到过乱码问题吧,很不好解决,因为现在的程序都是跨网络的,而且各个平台的编码都不一定都相同,例如windows给Linux发送了一段数据,声明这是gbk编码的数据,而Linux接收的数据又要求是utf-8的,这样的情况就是出现乱码的现象,其实socket传递的数据都是bytes类型的,而bytes是没有编码这一说的, 只要我们双方遵守一个规范的话,这样的话,能很好的解码bytes就不会出现Python乱码的问题。

二、bytearray

bytearray 是bytes的可变版本

str和bytes是不可变的

>>> b = b'abc'
>>> b[1] = b'B'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'bytes' object does not support item assignment

因为bytes是不可变的,因此我们在修改bytes数据的时候,抛出了TypeError的异常

bytearray的操作

>>> b = b'abc'
>>> b = bytearray(b)
>>> type(b)
<class 'bytearray'>
得到了一个bytearray的数据

之前提过了bytearray 是bytes的可变版本,那么下面来操作下如何修改bytearray的数据

>>> b[1] = b'B'   
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: an integer is required
抛出了异常,说明bytearry是不能直接修改数据的,必须将bytes转换成int类型才可以。

>>> b[1] = int(b'B')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: b'B'
发现bytes类型数据是不能直接转成int的,需要使用hex方法来转成16进制的数据,然后在转成int类型,从而修改bytearray的数据

>>> b
b'abc'
>>> b[1] = int(b'B'.hex(), 16)
>>> b
bytearray(b'aBc')
现在可以看出已经修改了数据,这也证实了bytearray是可变的

bytearray为什么需要一个可变的版本?

举个简单的例子来说明下为什么需要bytearray。
例如图像处理,当我们进行图像处理的时候,可能会进行多次,甚至上万次的变动,如果使用bytes那么就需要不断的从新开辟空间,
对资源的消费是非常大的,但是如果使用bytearray那么久只需要进行原地修改就好了,不会占用对于的空间。

相对于bytes来说,多了insert, append, extend, pop, remove, clear, reverse这些方法

并且bytearray是可以对索引进行操作的

bytearray的参数必须是int,因为bytearray操作的是单个字节

python没有byte类型,但是byte可以使用int来表示,因此bytearray的参数必须是int,而且参数是有范围的,只能是0 ~ 256

0 ~ 256 是8位无符号整数

我们要如何帮助您?

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注