
本文详解如何在 Python 中准确生成形如 123 的可打印十六进制转义字符串(非字节对象),并安全写入 serial.Serial 实例,重点厘清字符串字面量、原始字符串、字节编码与串口通信间的本质区别。
本文详解如何在 python 中准确生成形如 1xx323 的可打印十六进制转义字符串(非字节对象),并安全写入 serial.serial 实例,重点厘清字符串字面量、原始字符串、字节编码与串口通信间的本质区别。
在 Python 串口通信开发中,一个常见误区是混淆「字符串表示」与「实际传输字节」。例如,用户期望通过循环拼接得到字符串 "123"(即三个 ASCII 字符 '1', '2', '3' 对应的十六进制转义形式),但直接使用 ''+i 会导致语法错误或意外行为——因为 x 后必须紧跟两个十六进制数字,而 '1' 合法,'' + '1' 却被解析为字面量 (无效)加字符 '1',根本无法编译。
✅ 正确做法是:将 1 等作为普通字符串字面量构造,而非尝试用 x 转义序列动态生成。这意味着你需要手动拼接反斜杠、x 和两位十六进制数,并注意 Python 字符串中反斜杠需转义:
hex_str = ''
for i in '123':
hex_str += '\x3' + i # 注意:'\' 表示单个反斜杠字符
print(hex_str) # 输出:123(纯文本,共12个字符)⚠️ 但请务必注意:此 hex_str 是一个包含反斜杠和字母的普通字符串(str),并非二进制数据。它不能直接用于 serial.write() —— 因为 serial.Serial.write() 接收的是 bytes 或 bytearray,而非解释转义序列的字符串。
? 若要真正发送字节 0x31, 0x32, 0x33(即 ASCII 字符 '1','2','3'),应直接构造字节对象:
立即学习“Python免费学习笔记(深入)”;
# 方式1:使用 bytes() + list comprehension(推荐)
data_bytes = bytes([0x31, 0x32, 0x33]) # b'123'
# 方式2:从字符串 encode(更直观)
data_bytes = '123'.encode('latin-1') # 或 'ascii'
# 方式3:十六进制字符串转 bytes(适用于动态 hex 字符串)
hex_str_literal = '313233' # 不含 'x'
data_bytes = bytes.fromhex(hex_str_literal) # b'123'因此,原始串口写入代码应修正为:
import serial
sel = serial.Serial('/dev/tty.usbserial-FTCHMFWZ', 115200)
# ✅ 正确:发送真实字节 0x05
sel.write(b'')
# ✅ 正确:拼接 bytes 对象(注意 b'' 前缀)
payload = b'' + b'123' + b'' # 等价于 b'123'
sel.write(payload)
# ✅ 正确:发送结束字节
sel.write(b'')? 关键总结:
- '1' 是字符串字面量,表示单个字符 '1';'\x31' 是字符串 "\x31"(4个字符: x 3 1);
- 串口通信必须使用 bytes,切勿传入含未解析转义符的 str;
- 若需从变量动态生成字节,优先用 bytes([...])、.encode() 或 bytes.fromhex(),而非字符串拼接转义序列;
- 调试时可用 print(repr(data_bytes)) 查看真实字节内容,避免被打印效果误导。
掌握这一区分,即可稳健实现协议级串口指令构造。










