Python3 TypeError:必须是str,而不是bytes,使用sys.stdout.write()函数。

16 浏览
0 Comments

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

admin 更改状态以发布 2023年5月19日
0
0 Comments

如果你从子进程中得到的字节是使用sys.stdout.encoding编码(或一个兼容的编码,比如从一个输出ASCII的工具读取并输出到你的UTF-8标准输出),则接受的答案将能够正常工作。但正确的写入任意字节到标准输出的方式是:

sys.stdout.buffer.write(some_bytes_object)

这将只是按原样输出字节,而不是尝试将它们视为某种编码的文本。

0
0 Comments

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 读取 stdoutstdin 的数据类型从 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 ChangeLogPEP 358PEP 3112


1 在 ASCII 中,有一些很酷的技巧,用多字节字符集做不到;最著名的例子是“异或空格以切换大小写”(例如,chr(ord('a') ^ ord(' ')) == 'A')和“设置第六位来生成控制字符”(例如,ord('\t') + ord('@') == ord('I'))。ASCII 是在操作单个比特具有非常实际的性能影响的时代设计的。

2 是的,你可以使用函数注释,但这是一个相对较新的特性,并且很少使用。

0