
本文详解在 Python 3.x 中将含 ASCII 和十六进制转义字符(如 \xC7\xB4)的 AT 命令从字典安全发送至串口设备的方法,涵盖三种主流字节编码方案及类型校验实践。
本文详解在 python 3.x 中将含 ascii 和十六进制转义字符(如 `\xc7\xb4`)的 at 命令从字典安全发送至串口设备的方法,涵盖三种主流字节编码方案及类型校验实践。
在 Python 3 中,serial.Serial.write() 方法仅接受 bytes 类型参数,而不能直接写入 str(字符串)。当你在字典中定义类似 'AT+CGMM\xC7\xB4\r' 的命令时,该值本质是 Unicode 字符串(str),其中 \xC7\xB4 是 Python 源码中的十六进制转义序列,但其实际含义取决于编码方式——若未显式编码为字节,直接传入 write() 将触发 TypeError: expected bytes, got str。
以下是三种经过验证、生产可用的解决方案,按推荐度排序:
✅ 方法一:运行时动态编码(最灵活,推荐)
适用于命令需动态拼接或来源不可控(如用户输入、配置文件)的场景:
import serial
command = {
"cmd_a": 'AT\r',
"cmd_b": 'AT+HTTPINIT\xAE\r',
"cmd_c": 'AT+CGMM\xC7\xB4\r',
}
comport = serial.Serial('COM3', 115200, timeout=1)
cmd_to_send = command.get("cmd_c")
if isinstance(cmd_to_send, str):
comport.write(cmd_to_send.encode('latin-1')) # 关键:用 latin-1 而非 utf-8!
⚠️ 重要提示:对于含 \xAE、\xC7\xB4 等非 UTF-8 编码字符(常见于嵌入式 AT 指令集),应优先使用 'latin-1' 编码。因为 latin-1 将每个 Unicode 码点 1:1 映射为对应字节(U+00AE → 0xAE),而 utf-8 会对非 ASCII 字符进行多字节编码(如 \xC7 在 UTF-8 中可能被误解释为无效序列),导致 MCU 接收错误。'latin-1' 安全、高效、零失真。
✅ 方法二:字典预定义为字节字面量(最高效,推荐)
适用于命令固定、可提前确定的场景,避免运行时编码开销:
command = {
"cmd_a": b'AT\r',
"cmd_b": b'AT+HTTPINIT\xAE\r',
"cmd_c": b'AT+CGMM\xC7\xB4\r', # \xC7\xB4 直接作为字节存入
}
cmd_to_send = command.get("cmd_c")
if isinstance(cmd_to_send, bytes):
comport.write(cmd_to_send)
✅ 优势:无需编码转换;字节内容与 MCU 预期完全一致;类型安全,IDE 可静态检查。
⚠️ 方法三:bytes() 构造器(兼容性写法,慎用)
cmd_to_send = command.get("cmd_c")
if isinstance(cmd_to_send, str):
comport.write(bytes(cmd_to_send, 'latin-1'))
虽功能等效于方法一,但 bytes(str, encoding) 语法略冗长,且易与 bytes([0x41, 0x54]) 混淆,建议统一使用 .encode()。
? 类型校验与健壮性增强
为防止字典键缺失或值类型异常,建议封装为安全发送函数:
def send_at_command(comport, cmd_dict, key):
cmd = cmd_dict.get(key)
if cmd is None:
raise ValueError(f"Command key '{key}' not found in dictionary")
if isinstance(cmd, str):
cmd = cmd.encode('latin-1')
elif not isinstance(cmd, bytes):
raise TypeError(f"Command value must be str or bytes, got {type(cmd).__name__}")
return comport.write(cmd)
# 使用示例
send_at_command(comport, command, "cmd_c")
? 总结要点
- ✅ 所有串口写入必须使用
bytes,绝不可传str; - ✅ 含
\xNN的 AT 命令应统一用'latin-1'编码(非utf-8),确保十六进制字节精准透传; - ✅ 优先采用
b''字节字面量定义字典(方法二),兼顾性能与可读性; - ✅ 生产环境务必加入
isinstance()类型检查,避免运行时崩溃; - ✅ 发送后建议配合
comport.read()或timeout验证响应,形成完整通信闭环。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











