当前位置: 首页 > 面试题库 >

Python 3:如何指定stdin编码

田英卓
2023-03-14
问题内容

在将代码从Python 2移植到Python 3时,从标准输入读取UTF-8文本时遇到了这个问题。在Python 2中,这可以正常工作:

for line in sys.stdin:
    ...

但是Python 3需要 sys.stdin中的 ASCII ,如果输入中包含非ASCII字符,则会出现错误:

UnicodeDecodeError:’ascii’编解码器无法解码位置..中的字节..:序数不在范围内(128)

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

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

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

input_stream = codecs.getreader('utf-8')(sys.stdin)
for line in input_stream:
    ...

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


问题答案:

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')

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

从Python
3.7起,您还可以重新配置现有的std*包装器,前提是您在一开始就进行了配置(在读取任何数据之前):

# Python 3.7 and newer
sys.stdin.reconfigure(encoding='utf-8')


 类似资料:
  • 问题内容: 代码很简单: 有没有办法编译来自标准输出的代码? 我已经试过了: 和一些变体,但没有一个产生可执行文件。 只是一些澄清。我有一个预处理文件的程序,并生成另一个要编译的文件。我考虑过不创建此中间文件,而是直接生成目标文件。 问题答案: 编译器可能会告诉您: 尝试

  • 问题内容: 一切在命令行上都可以正常运行,但是当我将所需的内容转换为Java时,接收过程在stdin上什么都收不到。 这是我所拥有的: 脚本“ count-the-bytes”很简单: 输出表明该函数挂在’wc -c’行-永远不会到达’counted stdin bytes’行。 这是怎么回事?使用Jsch会有所帮助吗? 问题答案: 您可能希望在wc -c返回之前尝试关闭输出流。

  • 问题内容: 我得去查档案主.py以及儿童.py. 我正试图把一个字符串发送到主.py. 这是我不完整的代码: child.py I have no idea how to do this. I am running windows 10 with python 3.5.1 -谢谢 编辑:当我将参数发送回主.py,我无法重新打开 程序。操作系统重新打开在我的情况下没有用的程序。 这些程序是我尝试做的

  • 问题内容: 假设我有一个简单的应用程序,可以从stdin读取行并将其回显到stdout。例如: 我想编写一个测试案例,该案例写入stdin,然后将输出与输入进行比较。例如: 跑步给我以下内容: 我显然在这里做错了什么。我应该如何测试这种类型的代码? 问题答案: 这是一个写入stdin并从stdout读取的示例。请注意,它不起作用,因为输出首先包含“>”。不过,您可以对其进行修改以适合您的需求。

  • 问题内容: 我从一个需要标准输入重定向的Python项目开始,使用类似于以下的代码: 问题是,代码运行后,将显示以下内容: 输入内容:您输入的内容:Hello 有没有办法修改我的代码,以便显示以下内容? 输入内容:您好 您输入了:您好 我一直在搜寻高低,但尚未找到答案。如果有人有主意,我将不胜感激。谢谢! 问题答案: 我不确定为什么需要这样做,但是您可以始终这样做: 再说一次,根据需要交换自己的实