python教程—Python 3 TypeError:必须是str,而不是sys.stdout.write()的字节。-Python实用宝典

python教程—Python 3 TypeError:必须是str,而不是sys.stdout.write()的字节。

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

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

write(nextline)类型错误:必须是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.当unicode在90年代得到广泛应用时,出现了一种新的unicode类型
被添加到处理Unicode而不破坏已有的代码1。这是
实际上与str相同,但支持多字节。

在python3中有两种不同的类型:

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

In Python 2 implicitly assuming an encoding could cause a lot of problems; you
could end up using the wrong encoding, or the data may not have an encoding at
all (e.g. it’s a PNG image).
Explicitly telling Python which encoding to use (or explicitly telling it to
guess) is often a lot better and much more in line with the "Python philosophy"
of "explicit is better than implicit".

这个更改与python2不兼容,因为许多返回值已经更改,
导致像这样的微妙问题;这可能是主要原因
Python 3的采用是如此之慢。因为Python没有静态类型2
不可能用脚本(比如绑定的脚本)自动地更改它
版本2)。

  • You can convert str to bytes with bytes('h€llo', 'utf-8'); this should
    produce b'Hxe2x82xacllo'. Note how one character was converted to three
    bytes.
  • 可以使用b' h xe2x82xacllo'.decode('utf-8')将字节转换为str。

当然,UTF-8在您的示例中可能不是正确的字符集,所以请确保
使用正确的。

在你的代码中,nextline的类型是字节,而不是str,
从子进程读取stdout和stdin在python3中从str更改为
字节。这是因为Python不能确定使用哪种编码。它
可能使用与sys.stdin相同的方法。编码(您的系统的编码),
但这并不确定。

你需要替换:

    sys.stdout.write(nextline)

:

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

或者:

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

还需要修改if nextline == " to if nextline == b ",因为:

    >>> '' == b'' False

也看到< a href = " http://docs.python.org/3.0/whatsnew/3.0.html text-vs-data-instead-of-unicode-vs-8-bit”> Python 3的更新日志< / >、< a href = " http://www.python.org/dev/peps/pep-0358/ " > PEP 358 < / >,和< a href = " http://www.python.org/dev/peps/pep-3112/ " > PEP 3112 < / >。


有一些你可以用ASCII码做的小技巧是你不能用多字节字符集做的;最著名的例子是“xor with space to switch case”(例如chr('a') ^ ord(' ') == 'a')和“set six bit to make a control character”(例如ord('t') + ord('@') == ord('I'))。ASCII在设计之时,操作单个位是一种性能影响不可忽略的操作。

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

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

本文由 Python实用宝典 作者:Python实用宝典 发表,其版权均为 Python实用宝典 所有,文章内容系作者个人观点,不代表 Python实用宝典 对观点赞同或支持。如需转载,请注明文章来源。
4

发表评论