Python3使用pexpect报TypeError: cannot use a string pattern on a bytes-like object求助
问题根因
你之前尝试的encoding='utf-8'参数、pexpect.spawnu方案无效,核心原因是代码中使用了BytesIO作为logfile。pexpect 4.8.0在检测到logfile为字节流类型时,会自动忽略编码配置,强制输出字节流,因此你传入的字符串类型匹配规则self.PASSPHRASE_RE就会触发“字符串模式不能匹配字节对象”的类型错误。
可行解决方案
下面提供两种经过验证的修复方案,可根据你的业务需求选择:
方案1:修改匹配规则为字节类型(改动最小,无需调整现有IO配置)
直接将匹配规则从字符串类型转为字节类型即可适配现有字节流输出逻辑:
- 若
self.PASSPHRASE_RE是正则对象,将编译规则从字符串模式改为字节模式,例如将re.compile(r'你的正则规则')改为re.compile(rb'你的正则规则'),或者用re.compile(self.PASSPHRASE_RE.encode('utf-8'))做编码转换 - 若
self.PASSPHRASE_RE是纯字符串匹配,直接添加b前缀转为字节串即可
修改后代码示例:
import re buff = BytesIO() child = pexpect.spawn(path, args, logfile=buff, timeout=self.PASSPHRASE_TIMEOUT, **kwargs) while True: # 仅修改该行的匹配规则为字节类型 idx = child.expect([re.compile(self.PASSPHRASE_RE.encode('utf-8')), pexpect.EOF]) if idx == 0: # 注意sendline也要对应传字节串,否则可能触发新的类型错误 child.sendline(passphrase.encode('utf-8')) elif idx == 1: child.wait() break
方案2:调整IO类型适配字符串输出模式(保留原字符串匹配规则)
如果不想修改原有匹配规则,将BytesIO替换为StringIO,同时保留编码配置即可:
from io import StringIO buff = StringIO() # 保留encoding参数,此时pexpect全链路使用字符串类型 child = pexpect.spawn(path, args, logfile=buff, encoding='utf-8', timeout=self.PASSPHRASE_TIMEOUT, **kwargs) while True: # 原有匹配规则无需修改 idx = child.expect([self.PASSPHRASE_RE,pexpect.EOF]) if idx == 0: child.sendline(passphrase) elif idx == 1: child.wait() break
注意事项
- 若子进程输出存在非UTF-8字符,可在spawn参数中添加
errors='ignore'避免编码报错 - 方案1最终从
buff中读取的内容为字节串,需要自行调用decode('utf-8')转为字符串使用;方案2读取的内容直接为字符串,可直接使用
内容的提问来源于stack exchange,提问作者Amit Kumar Manjhi
相关产品推荐
相关产品推荐

