【凡哥写给嵌入式工程师的python入门教程】9. Python中的字节(bytes)与字节数组(bytearray)

时间:2023-01-11 18:08:07

0. 概要

本章凡哥主要给大家讲解了Python中的二进制数据对象bytes的声明与操作方式, bytes与字符串之间的转换.
最后介绍了bytearray, 它与bytes之间最大的区别在于bytes的元素声明后不可以修改.

1. 什么是字节?

【凡哥写给嵌入式工程师的python入门教程】9. Python中的字节(bytes)与字节数组(bytearray)

之前我们提到过,用不同的字符集来表示不同的字符, 然后字符集通过特定的二进制编码(encode)方式来转换为内存中的字节存储。
二进制数据通过反编码(decode)获取到我们的字符串。

在Python中是有专门的字节数组对象。

什么是字节?

字节(字节数组)是二进制数据组成的序列,其中每个元素由一个字节二进制组成。

1 byte(字节) = 8 bit(位) = 2 位16进制数值

取值范围 0 - 255.

2. bytes

我们换一种方式初始化字符串 使用unicode编码来表示不同的字符。

2.1 声明bytes对象

还记得我们如何声明一个字符串的么?

my_string = "Hi \u2119\u01b4\u2602\u210c\xf8\u1f24"
my_string
'Hi ℙƴ☂ℌøἤ'
type(my_string)
str

在python中字节数组的声明方式跟字符串的声明方式很像, 就是在字符串前面加一个b

bytes_arr = b"hello"

type(bytes_arr)
bytes
bytes_arr
b'hello'
bytes_arr == (b'h' b'e' b'l' b'l' b'o' )
True

2.2 打印bytes中的值

# 打印出bytes_arr中的数值, 我们可以看到他的类型是数值
for byte in bytes_arr:
    print(byte)
104
101
108
108
111

2.3 bytes的另外一种声明方式

# 我们可以换一种方法来初始化 bytes对象
bytes_arr2 = bytes([104, 101, 108, 108, 111])
print(bytes_arr2)
b'hello'

chr(bytes_arr[0])
'h'

2.4 编码-将字符串变为bytes

我们直接动手转换试一下.

# 我们测试一下汉字转换为字节
b'凡哥'
  File "<ipython-input-19-b780e2718ca4>", line 2
    b'凡哥'
         ^
SyntaxError: bytes can only contain ASCII literal characters.

这里提示我们bytes类型只可以包含ASCII编码的字符。

因为默认的bytes编码方式是ascii,不支持中文。
如果我们想让他支持中文应该怎么办?在初始化的时候需要使用别的编码方式。

反编码 decode 字节转换为字符串

2 = bytes("凡哥",encoding='utf8')  #必须制定编码格式

b2
b'\xe5\x87\xa1\xe5\x93\xa5'

我们可以看到,每个汉字在utf8编码中都会占据三个字节
其中 对应的是 \xe5\x87\xa1
对应的是\xe5\x93\xa5

print(b2)

# 我们将其打印看到的也是其编码
b'\xe5\x87\xa1\xe5\x93\xa5'

2.5 解码-将bytes变回字符串

# 如何将bytes对象变回我们之前的字符
# 我们需要重新解码 decode
fg_str = b2.decode(encoding="utf8")
print(fg_str)
type(fg_str)
凡哥

str

2.6 bytes中元素的对比

# 我们来做一下bytes的数值对比
b2[1] == b'\x87'
False
b2[1]
135
# 可以看到并不能对比, 原因是?
# 我们来看一下各自的类型

print(type(b2[1]))
print(type(b'\x87'))
<class 'int'>
<class 'bytes'>

一个是整数一个是bytes类型怪不得不可以。
所以正确的对比姿势应该是:

print(b2[1] == b'\x87'[0])
print(bytes([b2[1]]) == b'\x87')
True
True

2.7 尝试修改bytes中的值

# 这里我们尝试变更一下其中一个数值
bytes_arr[0] = b'w'[0]
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-64-e462446fa7d0> in <module>()
      1 # 这里我们尝试变更一下其中一个数值
----> 2 bytes_arr[0] = b'w'[0]


TypeError: 'bytes' object does not support item assignment

3. bytearray 字节数组

可以看到bytes对象在声明之后,就不可以更改其中的值, 类似我们之前提到过的tuple类型。

那有没有可以更改的数据类型, 这里我们就要提到bytearray, 类比我们之前讲过的list类型。

ba = bytearray(b'hello')
ba[0:1] = b'w'
print(ba)
bytearray(b'wello')

ba = bytearray(b'hello')
ba[0] = b'w'[0]
print(ba)
bytearray(b'wello')

字节数组的操作与数组操作类似,这里我们不做过多讲解。

4. 延伸阅读

http://blog.csdn.net/yatere/article/details/6606316

https://www.cnblogs.com/skiler/p/6687337.html

Python 中的字节与字节数组
http://python.jobbole.com/84839/