遇到‘endswith first arg must be bytes...’错误,如何正确拼接字节?
解决PyVISA与质量流量控制器通信的字节类型错误
在使用PyVISA与MKS946质量流量控制器通信时,遇到错误:endswith first arg must be bytes or a tuple of bytes, not str,报错指向comm方法中的self.mks946.write(prestring + command.encode('ascii'))行。
原代码如下:
class MKS946: def __init__(self, com_port): self.port = int(com_port) def __enter__(self): rm = pyvisa.ResourceManager() self.mks946 = rm.open_resource(f"ASRL{self.port}::INSTR") self.mks946.baud_rate = 9600 sleep(0.1) return self def __exit__(self, exc_type, exc_val, exc_tb): self.mks946.write("@253LOCK!OFF") self.mks946.close() def comm(self, command): """ Implement communication protocol """ prestring = b'@253' #endstring = b';FF' self.mks946.write(prestring + command.encode('ascii')) sleep(0.1) return_string = self.mks946.read_bytes(self.mks946.bytes_in_buffer) return return_string def get_id(self): return self.comm('SN') if __name__ == "__main__": with MKS946(4) as mfc_box: print(mfc_box.get_id())
错误原因
错误的根源并非comm方法里的字节拼接(这部分本身合法),而是__exit__方法中调用write时传入了字符串类型的命令"@253LOCK!OFF"。PyVISA在串口通信模式下,要求写入内容必须是字节类型,混合字符串和字节的写入操作会触发内部类型检查失败,导致endswith报错。
解决方案
统一所有write调用的参数为字节类型,同时优化comm方法的字节拼接逻辑,提升代码可读性:
- 修改
__exit__方法中的写入命令,前缀加b转为字节:
def __exit__(self, exc_type, exc_val, exc_tb): self.mks946.write(b"@253LOCK!OFF") self.mks946.close()
- 优化
comm方法的字节拼接,先拼接完整命令字符串再统一编码:
def comm(self, command): """ Implement communication protocol """ full_command = f"@253{command}".encode('ascii') self.mks946.write(full_command) sleep(0.1) return_string = self.mks946.read_bytes(self.mks946.bytes_in_buffer) return return_string
修改后的完整代码
from time import sleep import pyvisa class MKS946: def __init__(self, com_port): self.port = int(com_port) def __enter__(self): rm = pyvisa.ResourceManager() self.mks946 = rm.open_resource(f"ASRL{self.port}::INSTR") self.mks946.baud_rate = 9600 sleep(0.1) return self def __exit__(self, exc_type, exc_val, exc_tb): self.mks946.write(b"@253LOCK!OFF") self.mks946.close() def comm(self, command): """ Implement communication protocol """ full_command = f"@253{command}".encode('ascii') self.mks946.write(full_command) sleep(0.1) return_string = self.mks946.read_bytes(self.mks946.bytes_in_buffer) return return_string def get_id(self): return self.comm('SN') if __name__ == "__main__": with MKS946(4) as mfc_box: print(mfc_box.get_id())
内容的提问来源于stack exchange,提问作者luiz_iniciante
相关产品推荐
相关产品推荐

