当前位置: 首页 > 知识库问答 >
问题:

Python 3 TypeError:必须是str,而不是带有sys的字节。斯特杜特。写()

拓拔君博
2023-03-14

我正在寻找一种从python脚本运行外部进程并在执行过程中打印其标准输出消息的方法
下面的代码可以工作,但在运行时不打印标准输出。当它退出时,我得到以下错误:

系统。斯特杜特。写入(下一行)类型错误:必须是str,而不是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.

共有2个答案

晁国发
2023-03-14

而如果子进程中的字节是使用sys编码的,那么接受的答案就可以正常工作。斯特杜特。编码(或兼容编码,如从输出ASCII的工具读取,而您的标准输出使用UTF-8),将任意字节写入标准输出的正确方法是:

sys.stdout.buffer.write(some_bytes_object)

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

艾英范
2023-03-14

Python3处理字符串的方式稍有不同。最初,字符串只有一种类型:str。当unicode在90年代获得发展时,新的unicode类型被添加到处理unicode而不破坏原有的代码1。这实际上与str相同,但支持多字节。

在Python 3中有两种不同的类型:

  • 字节类型。这只是一个字节序列,Python不知道如何将其解释为字符。
  • str类型。这也是一个字节序列,但是Python知道如何将这些字节解释为字符。
  • 删除了单独的Unicode类型。str现在支持Unicode。

在Python 2中,隐式地假设编码可能会导致很多问题;你可能最终使用了错误的编码,或者数据可能根本没有编码(例如,它是一个PNG图像)。
显式地告诉Python使用哪种编码(或显式地告诉它去猜测)通常要好得多,也更符合“显式优于隐式”的“Python哲学”。

这一变化与Python2不兼容,因为许多返回值都发生了变化,导致了类似这样的微妙问题;这可能是Python3采用如此缓慢的主要原因。由于Python没有静态类型2,因此不可能使用脚本(例如捆绑的2to3)自动更改。

  • 您可以使用字节('h€llo','utf-8')str转换为bytes;这将产生b'H\xe2\x82\xacllo'。请注意如何将一个字符转换为三个字节

当然,UTF-8在您的情况下可能不是正确的字符集,因此请确保使用正确的字符集。

在您的特定代码片段中,nextline是类型bytes,而不是str,读取stdoutstdin子进程在Python 3中从str更改>到字节。这是因为Python不能确定它使用了哪种编码。它可能使用相同的sys.stdin.encoding(系统的编码),但不能确定。

您需要替换:

sys.stdout.write(nextline)

与:

sys.stdout.write(nextline.decode('utf-8'))

或者也许:

sys.stdout.write(nextline.decode(sys.stdout.encoding))

如果nextline='',您还需要将修改为如果nextline==b',因为:

>>> '' == b''
False

另请参见Python 3变更日志、PEP 358和PEP 3112。

1有一些简单的技巧,你可以用ASCII做,但你不能用多字节字符集做;最著名的例子是“xor与空间切换大小写”(例如chr(d('a')^d(' ')) =='A')和"设置第6位以使控制字符"(例如ord('\t')ord('@') == ord('I'))。ASCII是在操纵单个比特是一种对性能影响不可忽视的操作的时候设计的。

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

 类似资料:
  • 问题内容: 我已经将脚本从Python 2.7转换为3.2,并且有一个错误。 在最后一行,我得到了这个错误: 我已经安装了Python 3.2,并且已经安装了lxml-2.3.win32-py3.2.exe。 在Python 2.7上可以使用。 问题答案: 输出文件应处于二进制模式。

  • 问题内容: 我一直在寻找一种从python脚本运行外部进程并在执行期间打印其stdout消息的方法。 下面的代码有效,但是在运行时不输出标准输出。退出时,出现以下错误: sys.stdout.write(nextline)TypeError:必须为str,而不是字节 我正在使用python 3.3.2 问题答案: Python 3处理字符串有些不同。最初,字符串只有一种类型:。上世纪90年代,当u

  • 我有一个问题,我做了一个乒乓游戏,但我有一个问题,把分数打印到pyplay窗口。 我得到错误'TypeError:参数1必须是pygame.Surface,而不是str 我在文本中输入了blit,但出现了一个错误。我知道代码乱七八糟,我稍后会修复它

  • 问题内容: 我有以下抛出的非常基本的代码; 我尝试将解码设置为Data变量,如下所示,但是会引发相同的错误; 有什么建议? 问题答案: 您只是将其以错误的顺序放置,是无辜的错误。 (深入解答)。正如wim礼貌地指出的那样,在极少数情况下,他们可以选择UTF-16或UTF-32。在这种情况下,对于开发人员而言,这种情况将不那么常见,在这种情况下,他们将有意识地决定放弃宝贵的带宽。因此,如果遇到编码问

  • 我使用的是Python3.3,但在尝试pickle一个简单的字典时出现了一个隐秘的错误。 代码如下: 我得到:

  • 最近,我用Nginx Ingres控制器在k8s集群中构建了几个微服务,它们工作正常。 在处理微服务之间的通信时,我尝试了gRPC并成功了。然后我发现当微服务A- 后来,我对istio产生了兴趣。我已成功将其部署到群集。但是,我观察到它总是创建自己的负载均衡器,这与现有的Nginx入口控制器不匹配。 此外,我尝试了prometheus和grafana以及k9s。这些工具让我对pod的cpu和内存使