Python基础教程

014_Python字节串类型bytes

Python字节串类型bytes

Python字节串类型bytes的理解

什么是字节byte?

字节(byte)是计算机最小存储单元。每个字节由8位(bit)构成,每个位(bit)由二进制0或1构成。而前面讲的字符是计算机显示时的最小单元。

什么是字节串bytes?

Python字节串bytes是字节数组(元组),是变长类型(长度可变),是不可变类型(不可修改值)。

字节串bytes有什么用?

字节串bytes主要处理二进制形式数据,比如二进制文件读写,网口数据传输,串口数据协议解析等。

bytes类型是python3新增的一种数据类型,用来代表字节串。字符串由多个字符串构成,以字符为单位进行操作,字节串由多个字节构成,以字节为单位进行操作。他们除了操作单元不同,其他的用法基本相同,bytes类型数据也是不可变对象。

Python中的字节串bytes可以由字符串转换得来(使用str.encode())。二进制读写也是通过字节操作,每个字节包含8个二进制位。

Python中的字节串bytes表现形式上以字母"b"开始。

my_bytes1=b"abc"           # 字节串,默认编码是ascii  
my_str="abc"               # 字符串
my_bytes2=my_str.encode()  # 字符串转字节串,默认编码是utf-8

print(my_bytes1)           # b'abc'
print(my_str)              # abc
print(my_bytes2)           # b'abc'

也可以用"x"十六进制表示,比如“中”占3个字节。

print("字符转字节:",("中").encode())             # b'xe4xb8xad'

字符串编码与字节串

常见的编码(翻译表)如下。

  • ascii编码。使用一个字节来把二进制内容翻译成字符。只能翻译127个字符,主要是英文和常用符号,不支持中文。
  • unicode编码。使用两个以上字节来把二进制内容翻译成字符。能翻译各国文字,包括英文、中文等,但是占用空间大。

  • utf-8编码。动态使用一个及多个字节来把二进制内容翻译成字符。能翻译各国文字,包括英文、中文等,而且又能合理利用空间。

中文符号占用2个字节,无法使用ascii来表示,也就是说使用ascii来翻译中文所占用的内存就不对,翻译错了,或不让翻译。

my_bytes1=b"abc"           # 字节串,ascii
print(my_bytes1)           # b'abc'

my_bytes2=b"中国"           # 字节串无法用ascii翻译(编码)
print(my_bytes2)            # 上面错误了

运行结果

C:UsershccmaAnaconda3python.exe E:/wkp01/p00/test01/py001/t09.py
  File "E:/wkp01/p00/test01/py001/t09.py", line 4
    my_bytes2=b"中国"           # 字节串
             ^
SyntaxError: bytes can only contain ASCII literal characters.

Process finished with exit code 1

使用utf-8表示

my_bytes1="abc".encode()   # 字节串,默认utf-8
print(my_bytes1)           # b'abc'

my_bytes2="中国".encode()   # 字节串,默认utf-8
print(my_bytes2)            # 是字节

运行结果

C:UsershccmaAnaconda3python.exe E:/wkp01/p00/test01/py001/t09.py
b'abc'
b'xe4xb8xadxe5x9bxbd'

Process finished with exit code 0

从字节串转到字符串的过程使用decode(),这是encode()的逆过程。

b1=b"abc"
b2=b'xe4xb8xadxe5x9bxbd'
print(b1.decode())              # 默认用utf-8解码
print(b2.decode())              # 默认用utf-8解码

运行结果

C:UsershccmaAnaconda3python.exe E:/wkp01/p00/test01/py001/t09.py
abc
中国

Process finished with exit code 0

内存中的字节与显示形式的转换

计算机只认识二进制,所以字符串或字节串在内存和磁盘中都是二进制形式。然而,当Python程序显示字节(8bit)的二进制时,输出的却是十六进制形式。

从转换角度看,二进制就是十进制,也是十六进制。它们是一一对应的,可以相互转换。

Python中提供字节、字符与进制之间的转换,如下。

  • 字符转字节,用str.encode()
  • 字节转字符,用bytes.decode()
  • 字符转十进制,用ord()
  • 十进制转字符,用chr()
  • 十进制转二进制,用bin()
  • 二进制转十进制,用int(bstr,2)
  • 十进制转十六进制,用hex()
  • 十六进制转十进制,用int(hstr,16)
print("字符转字节:",("中").encode())             # b'xe4xb8xad'
print("字节转字符:",(b'xe4xb8xad').decode())  # 中
print("字符转十进制:",ord("中"))                  # 20013
print("十进制转字符:",chr(20013))                 # 中
print("十进制转二进制:",bin(3))                   # 0b11
print("二进制转十进制:",int("0b11",2))            # 3
print("二进制转十进制:",int("11",2))              # 3   可以不写0b前缀
print("十进制转十六进制:",hex(15))                # 0xf
print("十六进制转十进制:",int("0xf",16))          # 15

它们之间还可以嵌套使用,比如查看“中”的二进制。

print(ord("中"))        # 先看十进制 20013
print(bin(ord("中")))   # 再看十进制 0b100111000101101

二进制的原码、反码和补码

内存中存储的都是二进制。其实二进制有原码、反码和补码,内存中存储的是补码。

反码和补码出现的作用主要是为了解决负数计算问题。

一个字节的二进制有8位(bit),高位(左侧第一位)表示正或负的符号,后面七位表示数值。

有如下结论:

  • 正数的原码、反码和补码是一样的;
  • 负数的原码、反码和补码不一样,反码是原码数值位取反,补码是反码加1。

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

几个处理字节串的模块

struct模块,参见标准库,可以在字节串和Python其他数据类型之间打包和解包。
binascii模块,参见标准库,可以进行二进制和 ASCII 码互转。
ctypes模块,参见标准库,它提供了与 C 兼容的数据类型,并允许调用 DLL 或共享库中的函数。

这篇文章对您有用吗?

我们要如何帮助您?