Python 3:如何指定stdin编码

Sep*_*rvi 30 python unicode encoding stdin python-3.x

在将代码从Python 2移植到Python 3时,我在从标准输入读取UTF-8文本时遇到了这个问题.在Python 2中,这很好用:

for line in sys.stdin:
    ...
Run Code Online (Sandbox Code Playgroud)

但Python 3期望来自sys.stdin的 ASCII ,如果输入中有非ASCII字符,我会收到错误:

UnicodeDecodeError:'ascii'编解码器无法解码字节..位置..:序号不在范围内(128)

对于常规文件,我会在打开文件时指定编码:

with open('filename', 'r', encoding='utf-8') as file:
    for line in file:
        ...
Run Code Online (Sandbox Code Playgroud)

但是如何指定标准输入的编码?其他SO帖子建议使用

input_stream = codecs.getreader('utf-8')(sys.stdin)
for line in input_stream:
    ...
Run Code Online (Sandbox Code Playgroud)

但是,这在Python 3中不起作用.我仍然得到相同的错误消息.我正在使用Ubuntu 12.04.2,我的语言环境设置为en_US.UTF-8.

Mar*_*ers 63

Python 3里不能指望从ASCII sys.stdin.它将stdin以文本模式打开,并对使用的编码进行有根据的猜测.这个猜测可能归结为ASCII,但这不是一个给定的.请参阅有关如何选择编解码器的sys.stdin文档.

与在文本模式下打开的其他文件对象一样,该sys.stdin对象派生自io.TextIOBase基类 ; 它有一个.buffer指向底层缓冲IO实例的.raw属性(后者又有一个属性).

sys.stdin.buffer在新io.TextIOWrapper()实例中包装属性以指定不同的编码:

import io
import sys

input_stream = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)

或者,在运行python时将PYTHONIOENCODING环境变量设置为所需的编解码器.

从Python 3.7开始,您也可以重新配置现有的std*包装器,只要您在开始时(在读取任何数据之前)执行此操作:

# Python 3.7 and newer
sys.stdin.reconfigure(encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)

  • 什么是python2.6最接近的等价物? (2认同)
  • @Suncatcher:IDLE 是这里的 IDE,并用自定义对象替换了标准的“sys.stdout”对象。该类是 IDLE 内部实现的一部分,而不是标准库类。 (2认同)