当前位置: 首页 > 面试题库 >

Python 3 TypeError:必须为str,而不是sys.stdout.write()的字节

孔弘盛
2023-03-14
问题内容

我一直在寻找一种从python脚本运行外部进程并在执行期间打印其stdout消息的方法。
下面的代码有效,但是在运行时不输出标准输出。退出时,出现以下错误:

sys.stdout.write(nextline)TypeError:必须为str,而不是字节

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。上世纪90年代,当unicode获得关注时,新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)自动更改此 类型。

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

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

在特定的一段代码,nextline是一个类型bytes,而不是str,阅读stdout以及stdinsubprocess来自在Python3改strbytes。这是因为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可以完成一些巧妙的技巧,而使用多字节字符集则无法做到;最著名的例子是“带有空格的xor切换大小写”(例如chr(ord('a') ^ ord(' ')) == '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上可以使用。 问题答案: 输出文件应处于二进制模式。

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

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

  • 问题内容: 我一直在尝试更新一个名为libpynexmo的小型Python库以与Python 3一起使用。 我一直坚持这个功能: 遇到这个问题时,json会回应: 我在一些地方读到,应该为您传递带有附件的对象(在这种情况下为对象),但是它不适用于对象。 我不知道下一步该怎么做,但是由于我的整个1500行脚本是新转换为Python 3的,所以我不想回到2.7。 问题答案: 我最近写了一个小功能来发送

  • 我正在寻找一种从python脚本运行外部进程并在执行过程中打印其标准输出消息的方法 下面的代码可以工作,但在运行时不打印标准输出。当它退出时,我得到以下错误: 系统。斯特杜特。写入(下一行)类型错误:必须是str,而不是bytes 我正在使用python 3.3。2.

  • 问题内容: 以下是我的代码: 当我运行它时,它给了我 那么应该是哪种类型呢? 问题答案: 引发的唯一参数表示要引发的异常。这必须是异常实例或异常类(从Exception派生的类)。 尝试这个: