Python 3 - 将整数转换为“字节”并进行串行传输时的连接方式

4
经过长时间的搜索,我仍无法理解Python 3.2中处理“字节”和十六进制内容的方式。我知道我有误解,但似乎找不到正确的方法。
我的最终目标是使用Python串行模块传输一系列字节。一些字节是静态的,不会改变。其他字节的值应该在0-255之间变化。所有这些字节都需要合并在一起并一次性传输。(这是可编程显示器的指令。代码包含固定指令以设置背景颜色,然后是每个R、G和B值的一个字节。我正在尝试通过循环来测试颜色强度,但稍后我将希望能够对显示器上的实际功能执行此操作)。
一个完整的静态传输,经过测试成功,可能如下:
ser.write(b'\xAA\x11\x05\x00\x00\x00\xc3')  #this works great

同样地,我可以将它们压缩在一起,即:
ser.write(b'\xAA\x11\x05' + b'\x00\x00\x00\xc3')  #also works great

现在,如果我想要将这三个零值字节中的一个替换为一个变量,那么一切就都变得混乱了。在进行了很多实验后,我最终得到了一个据称可以将For循环的整数变量转换为与上述一系列字节相容的类型进行串联的内容:

SET_BG_COLOR = b'\xAA\x03\x03'
for r in range(0,255):
            red = hex(r).encode('utf-8')
            blue = hex(255-r).encode('utf-8')
            ser.write(SET_BG_COLOR + blue + b'\x00' + red + b'\xC3') #BGR format

迄今为止,hex(integer).encode('utf-8')是唯一一个不会因为无法连接到我试图塞入串行连接的其他内容而抛出错误的方法。但它并不起作用,当查看结果时:

>>> x = b'\05'
>>> x
b'\x05'
>>> y = hex(5).encode('utf-8')
>>> y
b'0x5'
>>> type(x)
<class 'bytes'>
>>> type(y)
<class 'bytes'>
>>> x + y
b'\x050x5'   #(this is what I get)
>>> z = b'\05'
>>> x + z
b'\x05\x05'  #(this is what I want)
>>> 

看起来,虽然它让我拼接字符串...但它似乎是一种字符串数据的二进制表示,或者类似的东西?所以它能让我连接字符串,但这不是真正的十六进制值?我是否错过了一种从x = 255到x = b'\FF'的显而易见的方法?还是我的整个方法都是错误的?-_- 感谢您的时间。

1个回答

7
你在这里混淆了Python字节文字的语法;你不需要生成文字语法,只需要生成字节值;bytes()类型也接受一系列整数
>>> bytes([255])
b'\xff'

应用到你的代码中:
SET_BG_COLOR = b'\xAA\x03\x03'
for r in range(0,255):
    red = bytes([r])
    blue = bytes([255 - r])
    ser.write(SET_BG_COLOR + blue + b'\x00' + red + b'\xC3') #BGR format

或者,更简单的方法是:
SET_BG_COLOR = [0xAA, 0x03, 0x03]
for r in range(0,255):
    ser.write(bytes(SET_BG_COLOR + [r, 0x00, 255 - r, 0xC3])) #BGR format

使用十六进制整数表示法。

r = 10 的演示:

>>> SET_BG_COLOR = [0xAA, 0x03, 0x03]
>>> r = 10
>>> bytes(SET_BG_COLOR + [r, 0x00, 255 - r, 0xC3])
b'\xaa\x03\x03\n\x00\xf5\xc3'
hex()函数每个字节输出4个字符;以文字0x开头,后面跟着整数的十六进制表示。编码为UTF8仍然是4个字节,例如对于整数值10,它是b'\x30\x78\x30\x31',而不是你想要的实际字节b'\x10'

还要注意Python 2的情况,参见https://dev59.com/v2025IYBdhLWcg3wnXWg。 - Luqmaan
谢谢。这让我抓狂了。现在我的桌子上有一个漂亮的彩色循环显示器 :) - r00x
嗯。实际上,IDLE在这里给出了一个提示:如果您键入“bytes(”,弹出菜单会显示“()bytes(iterable_of_ints)-> bytes”……应该点击“iterable”,暗示我可以使用单项列表。-_- 最初,我输入的内容类似于“bytes(5)”,并想知道为什么我从另一侧得到了5个空字节! - r00x

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接