Python 3 处理字符串有点不同。最初只有一种类型
字符串:str。当 unicode 在 90 年代获得关注时,新的 unicode 类型
已添加以处理 Unicode,而不会破坏预先存在的代码1。这是
实际上与str 相同,但支持多字节。
在 Python 3 中有两种不同的类型:
-
bytes 类型。这只是一个字节序列,Python不知道
关于如何将其解释为字符的任何信息。
-
str 类型。这也是一个字节序列,但是 Python 知道如何
将这些字节解释为字符。
- 单独的
unicode 类型已删除。 str 现在支持 unicode。
在 Python 2 中,隐式假设编码可能会导致很多问题;你
最终可能会使用错误的编码,或者数据可能没有编码
全部(例如,它是 PNG 图像)。
明确告诉 Python 使用哪种编码(或明确告诉它
猜测)通常更好,更符合“Python哲学”
的“explicit is better than implicit”。
此更改与 Python 2 不兼容,因为许多返回值已更改,
导致像这样的微妙问题;这可能是主要原因
Python 3 的采用非常缓慢。由于 Python 没有静态类型2
不可能使用脚本自动更改它(例如捆绑的
2to3)。
- 您可以使用
bytes('h€llo', 'utf-8') 将str 转换为bytes;这应该
产生b'H\xe2\x82\xacllo'。请注意如何将一个字符转换为三个
字节。
- 您可以使用
b'H\xe2\x82\xacllo'.decode('utf-8') 将bytes 转换为str。
当然,在您的情况下,UTF-8 可能不是正确的字符集,所以请确保
使用正确的。
在您的特定代码中,nextline 的类型为 bytes,而不是 str,
从 subprocess 读取 stdout 和 stdin 在 Python 3 中从 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 做一些巧妙的技巧,而用多字节字符集却做不到;最著名的例子是“xor with space to switch case”(例如chr(ord('a') ^ ord(' ')) == 'A')和“设置第6位以制作控制字符”(例如ord('\t') + ord('@') == ord('I'))。 ASCII 是在操作单个位是一项对性能影响不可忽视的操作时设计的。
2是的,你可以使用函数注解,但它是一个比较新的特性,很少使用。