Python3 TypeError:必须是str,而不是bytes,使用sys.stdout.write()函数。
Python3 TypeError:必须是str,而不是bytes,使用sys.stdout.write()函数。
我在寻找一种在 python 脚本中运行外部进程并在执行过程中打印其 stdout 消息的方法。
下面的代码有效,但在运行期间不打印 stdout 输出。当它退出时,我会收到以下错误:
sys.stdout.write(nextline) TypeError:must be str,not bytes
p = subprocess.Popen(["demo.exe"],stdout = subprocess.PIPE, stderr= subprocess.PIPE) # Poll process for new output until finished while True: nextline = p.stdout.readline() if nextline == '' and p.poll() != None: break sys.stdout.write(nextline) sys.stdout.flush() output = p.communicate()[0] exitCode = p.returncode
我正在使用 python 3.3.2
Python 3 处理字符串的方式略有不同。最开始只有一种字符串类型:str
。当 Unicode 在 90 年代得到推广时,添加了新的unicode
类型以处理 Unicode,同时又不破坏现有的代码1。实际上,这与str
基本相同,但有多字节支持。
在 Python 3 中有两种不同类型:
bytes
类型。这只是一系列字节,Python对如何将其解释为字符一无所知。str
类型。这也是一系列字节,但Python知道如何将这些字节解释为字符。unicode
类型已被删除。现在,str
支持Unicode。
在 Python 2 中,隐式地假定编码可能会引起很多问题。你可能会使用错误的编码,或者数据可能根本没有编码(例如PNG图像)。
明确告诉Python使用哪种编码(或明确告诉它去猜测)通常会更好,也更符合 “明确优于隐含” 的 Python 哲学”。
这种变化与 Python 2 不兼容,因为许多返回值已经改变,导致诸如这样的微妙问题;这可能是 Python 3 采用率缓慢的主要原因。由于 Python 没有静态类型2,因此无法使用脚本(如捆绑的2to3
)自动更改。
- 你可以使用
bytes('h € llo','utf-8')
将str
转换为bytes
;这应该可以生成b'H\xe2\x82\xacllo'
。请注意,其中一个字符已转换为三个字节。 - 你可以使用
b'H € llo'.decode('utf-8')
将bytes
转换为str
。
当然,UTF – 8 可能不是你的情况下的正确字符集,请确保使用正确的字符集。
在你特定的代码中,nextline
的类型是 bytes
而不是 str
,
在 Python 3 中,从 subprocess
读取 stdout
和 stdin
的数据类型从 str
变为 bytes
。这是因为 Python 不确定使用的编码方式是什么。
它可能使用与你的系统相同的编码方式,即 sys.stdin.encoding
,但它不能确定。
你需要将
sys.stdout.write(nextline)
替换为:
sys.stdout.write(nextline.decode('utf-8'))
或者可能替换为:
sys.stdout.write(nextline.decode(sys.stdout.encoding))
你还需要将 if nextline == ''
修改为 if nextline == b''
,因为:
>>> '' == b'' False
请参考Python 3 ChangeLog、PEP 358 和 PEP 3112。
1 在 ASCII 中,有一些很酷的技巧,用多字节字符集做不到;最著名的例子是“异或空格以切换大小写”(例如,chr(ord('a') ^ ord(' ')) == 'A'
)和“设置第六位来生成控制字符”(例如,ord('\t') + ord('@') == ord('I')
)。ASCII 是在操作单个比特具有非常实际的性能影响的时代设计的。
2 是的,你可以使用函数注释,但这是一个相对较新的特性,并且很少使用。