在上位机开发过程中,经常要解析从下位机(比如plc)读来的数据,python解析数据有好几种方式。今天这里列出一个方法,这种方法很少人用,理解起来比较困难。python是一种完全面向对象的语言,它比c++,c#彻底。python的数据类型也是一种对象,如bool对象,int对象,float对象。既然是对象,肯定就会有属性和方法。这里就是利用这个思路来解析字节数组的,字节数组也是个对象。直接上代码:
byt = bytearray(b'\x00\x00\x7e\x0f')
print(byt)
one = bool.__bool__((byt.__getitem__(0)>>0 & 0b1))
two = bool.__bool__((byt.__getitem__(0)>>1 & 0b1))
three = bool.__bool__((byt.__getitem__(0)>>2 & 0b1))
four = bool.__bool__((byt.__getitem__(0)>>3 & 0b1))
five = bool.__bool__((byt.__getitem__(0)>>4 & 0b1))
for i in range(32):
a=bool.__bool__(byt.__getitem__(i//8)>>i%8 & 0b1)
print(f"{i//8}.{i%8}=",a)
运行结果:
0.0= False
0.1= False
0.2= False
0.3= False
0.4= False
0.5= False
0.6= False
0.7= False
1.0= False
1.1= False
1.2= False
1.3= False
1.4= False
1.5= False
1.6= False
1.7= False
2.0= False
2.1= True
2.2= True
2.3= True
2.4= True
2.5= True
2.6= True
2.7= False
3.0= True
3.1= True
3.2= True
3.3= True
3.4= False
3.5= False
3.6= False
3.7= False
在这段代码中,首先创建了一个字节数组 `byt`,内容为 `b'\x00\x00\x7e\x0f'`,然后通过一系列位运算和逻辑运算,获取了字节数组中各个位的值,并将其转换为布尔类型。最后使用循环打印了字节数组中每一个位的布尔值。
逐步解释这段代码的执行过程:
1. `byt = bytearray(b'\x00\x00\x7e\x0f')`:创建了一个长度为4的字节数组 `byt`,内容为十六进制 `00 00 7e 0f` 对应的字节串。
2. 通过一系列类似的操作,获取了字节数组中各个位的值,并将其转换为布尔类型。例如,`one` 获取字节中第一个位的值,`two` 获取第二位的值,依次类推。
3. `for i in range(32):`:循环遍历了0到31的整数。
4. `a=bool.__bool__(byt.__getitem__(i//8)>>i%8 & 0b1)`:对于每一位,通过位运算和逻辑运算获取其值,并转换为布尔类型。`i//8` 表示字节的索引(0到3),`i%8` 表示位在字节中的偏移量(0到7)。
byt = bytearray(b'\xff\x00\x7e\x0f')
a=int.from_bytes(byt[2:3], 'big',signed=False)
b=int.from_bytes(byt[2:4],byteorder='big',signed=False)
c=int.from_bytes(byt,byteorder='big',signed=True)
print(a,b,c)
输出:126 32271 -16744945
在 `int.from_bytes()` 方法中,`signed` 参数用于指定是否将解释的字节序列作为有符号整数解释。如果 `signed=True`,则解释的整数将被视为有符号整数,即可以表示正数和负数;如果 `signed=False`,则解释的整数将被视为无符号整数,只能表示非负数。
举个例子,如果我们有一个字节序列 `b'\xFF'`,按照 big-endian 字节顺序解释,如果 `signed=True`,那么这个字节序列将被解释为有符号整数 `-1`;如果 `signed=False`,那么这个字节序列将被解释为无符号整数 `255`。
在使用 `int.from_bytes()` 方法时,根据您的需求来选择 `signed` 参数的取值,以确保正确地解释字节序列为有符号或无符号整数。
还有就是python中不像C,C#那样分的非常细,右uint ,sint ,lint 等来表示字节长度。python中我们可以用索引来拿确定长度。前提是你要知道你要的数据在哪几个字节里面。
3.float
要将浮点数转换为字节数组,可以使用 `struct` 模块中的 `pack` 函数。`struct.pack()` 函数可以将数据按照指定的格式转换为字节序列。
下面是一个示例代码,演示如何将浮点数转换为字节数组:
```python
import struct
# 定义一个浮点数
f = 3.14159
# 使用 struct.pack() 将浮点数转换为字节数组
byte_array = struct.pack('d', f) # 'd' 表示双精度浮点数类型
print(byte_array)
```
在上面的示例中,`f` 是一个浮点数,`struct.pack('d', f)` 将浮点数 `f` 转换为字节数组。在 `struct.pack()` 中,`'d'` 表示双精度浮点数类型。
通过这种方法,可以将浮点数转换为字节数组。如果您需要将字节数组再转换回浮点数,可以使用 `struct.unpack()` 函数。例如:
```python
# 将字节数组转换回浮点数
unpacked_f = struct.unpack('d', byte_array)[0]
print(unpacked_f)
```