Python:从stdin读取时出现UnicodeEncodeError

6 投票
3 回答
4987 浏览
提问于 2025-04-15 20:33

当我运行一个从标准输入读取的Python程序时,出现了以下错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 320: ordinal not in range(128)

我该怎么解决这个问题呢?

注意:这个错误发生在antlr内部,出错的那一行看起来是这样的:

        self.strdata = unicode(data)

因为我不想修改源代码,所以我想传入一些可以接受的内容。

输入的代码看起来是这样的:

#!/usr/bin/python
import sys
import codecs
import antlr3
import antlr3.tree
from LatexLexer import LatexLexer
from LatexParser import LatexParser


char_stream = antlr3.ANTLRInputStream(codecs.getreader("utf8")(sys.stdin))
lexer = LatexLexer(char_stream)
tokens = antlr3.CommonTokenStream(lexer)
parser = LatexParser(tokens)
r = parser.document()

3 个回答

1

这里有一篇很棒的文章,讲述了Python是如何处理编码的:

如何在Python中使用UTF-8

1

你遇到的这个错误不是在输入的时候出现的,而是在尝试输出读取的数据时出现的。你应该对读取的数据进行解码,而不是一直处理字节串,应该把这些Unicode字符处理好。

14

问题是,当从标准输入(stdin)读取数据时,Python会使用系统默认的编码方式来解码这些数据。

>>> import sys
>>> sys.getdefaultencoding()
'ascii'

输入的数据很可能是UTF-8编码或者Windows的CP-1252编码,所以程序在遇到非ASCII字符时就会出错。

为了把sys.stdin转换成一个使用正确解码器的流,我使用了:

import codecs
char_stream = codecs.getreader("utf-8")(sys.stdin)

这样就解决了问题。

顺便提一下,这就是ANTLR的FileStream用来打开一个指定文件名的文件(而不是指定的流)的方法:

    fp = codecs.open(fileName, 'rb', encoding)
    try:
        data = fp.read()
    finally:
        fp.close()

另外,我发现对于字符串,

a_string.encode(encoding) 

这个方法也很有用。

撰写回答