Python:从stdin读取时的UnicodeEncodeError

han*_*ier 6 python unicode stdin antlr

运行从stdin读取的Python程序时,出现以下错误:

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

我该如何解决?

注意:错误发生在antlr内部,并且该行看起来像:

        self.strdata = unicode(data)
Run Code Online (Sandbox Code Playgroud)

由于我不想修改源代码,我想传递一些可接受的内容.

输入代码如下所示:

#!/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()
Run Code Online (Sandbox Code Playgroud)

han*_*ier 14

问题是,当从stdin读取时,python使用系统默认编码对其进行解码:

>>> import sys
>>> sys.getdefaultencoding()
'ascii'
Run Code Online (Sandbox Code Playgroud)

输入很可能是UTF-8或Windows-CP-1252,因此程序会阻塞非ASCII字符.

要使用正确的解码器将sys.stdin转换为流,我使用了:

import codecs
char_stream = codecs.getreader("utf-8")(sys.stdin)
Run Code Online (Sandbox Code Playgroud)

这解决了问题.

顺便说一句,这是ANTLRs FileStream用于打开具有给定文件名(而不是给定流)的文件的方法:

    fp = codecs.open(fileName, 'rb', encoding)
    try:
        data = fp.read()
    finally:
        fp.close()
Run Code Online (Sandbox Code Playgroud)

BTW#2:对于我发现的字符串

a_string.encode(encoding) 
Run Code Online (Sandbox Code Playgroud)

有用.