为什么Python的IDLE和控制台会产生不同的结果

3
我编写了一个简单的Python脚本,用于将中文标点翻译为英文。
import codecs, sys

def trcn():
    tr = lambda x: x.translate(str.maketrans(""",。!?;:、()【】『』「」﹁﹂“”‘’《》~¥…—×""", """,.!?;:,()[][][][]""''<>~$^-*"""))
    out = codecs.getwriter('utf-8')(sys.stdout)
    for line in sys.stdin:
        out.write(tr(line))

if __name__ == '__main__':
    if not len(sys.argv) == 1:
        print("usage:\n\t{0} STDIN STDOUT".format(sys.argv[0]))
        sys.exit(-1)
    trcn()
    sys.exit(0)

但是 UNICODE 出了些问题。 我无法通过。错误信息:

Traceback (most recent call last):
  File "trcn.py", line 13, in <module>
    trcn()
  File "trcn.py", line 7, in trcn
    out.write(tr(line))
  File "C:\Python31\Lib\codecs.py", line 356, in write
    self.stream.write(data)
TypeError: must be str, not bytes

之后,我在IDLE和控制台中测试了out.write()函数,结果不同。我不知道为什么。 IDLE环境下:
Python 3.1.2 (r312:79149, Mar 21 2010, 00:41:52) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import sys,codecs
>>> out = codecs.getwriter('utf-8')(sys.stdout)
>>> out.write('hello')
hello
>>>

在控制台中

Python 3.1.2 (r312:79149, Mar 21 2010, 00:41:52) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys,codecs
>>> out = codecs.getwriter('utf-8')(sys.stdout)
>>> out.write('hello')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python31\Lib\codecs.py", line 356, in write
    self.stream.write(data)
TypeError: must be str, not bytes
>>>

平台:Windows XP EN
3个回答

6

您的编码输出以字节形式从编码器中输出,因此必须传递给 sys.stdout.buffer

out = codecs.getwriter('utf-8')(sys.stdout.buffer)

我不确定为什么你的代码在IDLE和控制台中表现不同,但以上内容可能会有所帮助。也许IDLE的sys.stdout实际上期望字节而不是字符(希望它有一个.buffer也期望字节)。


谢谢!这个问题困扰了我两天。我尝试了"out = codecs.getwriter('utf-8')(sys.stdout)",它在Linux上可以工作,但在Windows上(甚至在cygwin中)无法工作。 - aiGuru

1

IDLE将stdout重定向到其自己的GUI输出。它显然接受字节和字符串,这是正常的stdout不支持的。

要么将其解码为Unicode,要么将其打印到sys.stdout.buffer。


-1

很明显控制台的编码不是UTF-8。当在控制台中调用Python时,有一种可选参数可以指定编码方式。请参考Python文档寻找解决方法。


谢谢。我一直以为编解码器的输出是Unicode字符串而不是字节,现在清楚多了。 - Gnu Engineer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接