Python字节流

我们知道在计算机存储中,最小的存储单位是字节。每个字节有 8 位,所以每个字节的取值范围是 0~255。

在早期,使用一个字节来表示一个字符,这就是有名的 ACSII 码。表1所示是 ASCII 码的定义,不过我们仅列出了前面的 128 个字符,这也是最早期的 ASCII 码。

表1:ASCII 编码一览表
ASCII码值 含 义
0 空字符,在有些语言中作为字符串的结尾字符使用
1 标题开始
2 正文开始
3 正文结束
4 传输结束
5 请求
6 收到通知
7 响铃
8 退格,相当于删除前一个字符
9 水平制表符
10 换行键
11 垂直制表符
12 换页键
13 回车键
14 不用切换
15 启用切换
16 数据链路转义
17 设备控制1
18 设备控制2
19 设备控制3
20 设备控制4
21 拒绝接收
22 同步空闲
23 结束传输块
24 取消
25 媒介结束
26 代替
27 换码
28 文件分隔符
29 分组符
30 记录分隔符
31 单元分隔符
32 空格,也就是相当于按了键盘上最长的那个键
33 !(叹号),不是中文的叹号,对应的是键盘上和1共用的那个键
34 "(双引号),不是中文的双引号
35 #(井号),也就是 Python 中的注释开始的字符
36 $(美元符)
37 %(百分号),就是整数取余数的那个操作符
38 &,就是整数按位与的那个操作符
39 '(单引号)
40 ((开括号)
41 )(闭括号)
42 *,就是整数乘法运算符
43 +(加号)
44 ,(逗号)
45 -(减号)
46 .(小数点)
47 /(除号),也可以为目录路径分隔符,如 c:/temp/a.py
48 数字字符 0。数字字符是连续的,0 和 1 相差一个码,1 和 2 也相差一个码,依次类推
49 数字字符1
50 数字字符2
51 数字字符3
52 数字字符4
53 数字字符5
54 数字字符6
55 数字字符7
56 数字字符8
57 数字字符9
58 : 冒号
59 ; 分号
60 < 小于号
61 = 等号,在 Python 中作为赋值符号使用
62 > 大于号
63 ? 问号
64 @ 电子邮件符号
65 大写字母A。大写字母也是连续的,A 和 B 相差一个码,B 和 C 也相差一个码,依次类推
66 大写字母B
67 大写字母C
68 大写字母D
69 大写字母E
70 大写字母F
71 大写字母G
72 大写字母H
73 大写字母I
74 大写字母J
75 大写字母K
76 大写字母L
77 大写字母M
78 大写字母N
79 大写字母O
80 大写字母P
81 大写字母Q
82 大写字母R
83 大写字母S
84 大写字母T
85 大写字母U
86 大写字母V
87 大写字母W
88 大写字母X
89 大写字母Y
90 大写字母Z
91 [,这个在 Python 中作为列表的开始符
92 \(反斜杠),通常作为转义字符使用,比如“\n”表示换行符
93 ]
94 ^,在Python中作为异或操作符
95 _(下划线)
96 `
97 小写字母a。小写字符也是连续的,a 和 b 相差一个码,b 集合 c 相差一个码,依次类推
98 小写字母b
99 小写字母c
100 小写字母d
101 小写字母e
102 小写字母f
103 小写字母g
104 小写字母h
105 小写字母i
106 小写字母j
107 小写字母k
108 小写字母l
109 小写字母m
110 小写字母n
111 小写字母o
112 小写字母p
113 小写字母q
114 小写字母r
115 小写字母s
116 小写字母t
117 小写字母u
118 小写字母v
119 小写字母w
120 小写字母x
121 小写字母y
122 小写字母z
123 {
124 |,在 Python 中表示或的位操作
125 }
126 ~,在 Python 中表示取反的位操作
127 删除,就是按了 Del 键的输入

由于 ASCII 码最多只能表示 256 个字符,所以非拉丁字母就很难用 ASCII 码表示。为了解决该问题,人们就定义了 Unicode,单个字符用 16 位或者 32 位来表示。这时字符和字节之间就没有直接对应的关系了。

在 Python 中,字符串和字节流是两个不同的数据类型。字节流主要用在二进制数据、网络传输的数据方面,字符串则用在文本文件、用户 IO 等方面。字节流的定义如下:
>>> var1 = b'abc'  # 定义字节流,3个字节,内容依次是a、b、c
>>> type(var1)     # 查看其类型
<class 'bytes'>

在 Python 中,字节流和字符串之间是可以相互转换的。尤其是在拉丁字母组成的字符串和字节流之间的相互转换是很简单的。
>>> 'abc'.encode("ascii")   # 将字符串按照ASCII编码方式来编码
b'abc'                      # 得到字节流
>>> b'abc'.decode("ascii")  # 将字节流按照ASCII编码方式来解码
'abc'

需要注意的是,并不是所有的字节流都可以用任意编码方式来解码。
>>> b'abc'.decode("utf-8")   # 用utf-8来解码是没有问题的
'abc'
>>> b'abc'.decode("utf-16")  # 用utf-16来解码是有问题的
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x63 in position 2:
truncated data