Python 中的字节与字节数组
admin
2023-07-31 00:44:49
0

之前介绍了 Python 中的字符串类型,字符串类型是对人类友好的符号,但计算机只认识一种符号,那就是二进制(binary)数,或者说是数字:
OpenCV

上面这张图片来自 OpenCV,非常直观地解释了计算机处理的信息与我们看到的图像之间的关系。回到 Python 对字节和字节数组的定义:

The core built-in types for manipulating binary data are bytes and bytearray.

1Byte of ASCII

为了用计算机可以理解的数字描述人类使用的字符,我们需要一张数字与字符对应的表。我们都知道在计算机中 1 byte = 8bits,可以存储 0~255 共256个值,也就是说 1byte 最多可以表示 256 个字符,在最初的计算机世界中,256 足以容纳所有大小写英文字母和 0~9 阿拉伯数字以及一些常用的符号,于是就有了 ASCII 编码:

ascii

在 Python 中创建字节与字符串类似,只不过需要在引号外面加一个前缀b

123 print(b\”Python\”)python = (b\’P\’ b\’y\’ b\”t\” b\’o\’ b\’n\’)print(python)

12 b\’Python\’b\’Pyton\’

Bytes 代表的是(二进制)数字的序列,只不过在是通过 ASCII 编码之后才是我们看到的字符形式,如果我们单独取出一个字节,它仍然是一个数字:

1 print(b\”Python\”[0])

1 80

我们可以用 b\"*\" 的形式创建一个字节类型,前提条件是这里的 * 必须是 ASCII 中可用的字符,否则将会超出限制:

1 print(b\”雨\”)

1234   File \”\”, line 1    print(b\”雨\”)         ^SyntaxError: bytes can only contain ASCII literal characters.

错误提示说明:字节类型只能允许 ASCII 字符。

0~127~255

那么问题来了,我们发现上面的 ASCII 表里面所有的字符只占据了 [31, 127],那对于这一范围之外的数字我们要怎么才能表示为字节类型?答案就是用特殊的转义符号x+十六进制数字 :

12 print(b\’xff\’[0])print(b\’x24\’)

12 255b\’$\’

反过来我们也可以将数字(0~255)转变成转义后的字节类型:

12 print(bytes([24]))print(bytes([36,36,36])) # 记住字节类型是一个序列

或者直接从十六进制得来:

123456 print(bytes.fromhex(\”7b 7d\”)) # 逆运算print(b\'{ }\’.hex()) int(b\’ \’.hex(), base=16)

1234 b\'{}\’7b207d 32

encode

字符串有 decode 方法,而字节有 encode 方法,我们这里先简单看一下 encode(\'ascii\') 。对于给定的字符我们可以通过编码得到它在编码表里面的坐标(即码位),因此对字符进行encode(\'ascii\')操作是找到其在 ASCII 中的位置:

12 print(\”$\”.encode(\’ascii\’))print(\”$\”.encode(\’ascii\’)[0])

12 b\’$\’36

也就是说字符 \"$\" (0x07中已经介绍过这是一个 Unicode 编码的字符)在 ASCII 中的位置就是 $(或者说36)。

可是如果我们对一些奇怪的字符进行 ASCII 编码,就会发生:

123

于是就得到了我们最熟悉的错误:ordinal not in range(128),至于为什么是 128,现在应该很好理解了吧!

字节数组

和字符串一样,字节类型也是不可变序列,而字节数组就是可变版本的字节,它们的关系就相当于listtuple

123 ba = bytearray(b\’hello\’)ba[0:1] = b\’w\’print(ba)

12 bytearray(b\’wello\’) 

由于和字符串一样是序列类型,字节和字节数组可用的方法也类似,这里就不一一列举了。

总结

  1. 字节(字节数组)是二进制数据组成的序列,其中每个元素由8bit二进制即1byte亦即2位十六进制数亦亦即0~255组成;
  2. 字节是计算机的语言,字符串是人类语言,它们之间通过编码表形成一一对应的关系;
  3. 最小的 ASCII 编码表只需要一位字节,且只占用了其中 [31,127] 的码位;

关于字节与字符串之间的关系,将在下一期0x08详细介绍。

参考

  1. Pragmatic Unicode

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...