使用Python3编码打印到标准输出

使用Python3编码打印到标准输出,python,python-3.x,character-encoding,Python,Python 3.x,Character Encoding,我有一个Python 3程序,可以从Windows-1252编码的文件中读取一些字符串: with open(file, 'r', encoding="cp1252") as file_with_strings: # save some strings 后来我想写信给stdout。我试着做: print(some_string) # => UnicodeEncodeError: 'ascii' codec can't encode character '\xe9' in posi

我有一个Python 3程序,可以从Windows-1252编码的文件中读取一些字符串:

with open(file, 'r', encoding="cp1252") as file_with_strings:
    # save some strings
后来我想写信给stdout。我试着做:

print(some_string)
# => UnicodeEncodeError: 'ascii' codec can't encode character '\xe9' in position 180: ordinal not in range(128)

print(some_string.decode("utf-8"))
# => AttributeError: 'str' object has no attribute 'decode'

sys.stdout.buffer.write(some_str)
# => TypeError: 'str' does not support the buffer interface

print(some_string.encode("cp1252").decode("utf-8"))
# => UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 180: invalid continuation byte

print(some_string.encode("cp1252"))
# => has the unfortunate result of printing b'<my string>' instead of just the string

我在这里挠头。我想打印从文件中获得的字符串,就像它在cp1252中显示的那样。在我的终端中,当我处理更多的$file时,这些字符显示为问号,所以我的终端可能是ascii


我想澄清一下!谢谢

对于任何有同样问题的人,我最终做了:

to_print = (some_string + "\n").encode("cp1252")
sys.stdout.buffer.write(to_print)
sys.stdout.flush() # I write a ton of these strings, and segfaulted without flushing

对于任何有同样问题的人,我最终做了:

to_print = (some_string + "\n").encode("cp1252")
sys.stdout.buffer.write(to_print)
sys.stdout.flush() # I write a ton of these strings, and segfaulted without flushing
当你用cp1252编码时,你必须用同样的方法解码

例如:

这将打印解码后在cp1252中编码的hi hello\n

当你用cp1252编码时,你必须用同样的方法解码

例如:


这将打印解码后在cp1252中编码的hi hello\n。

您正在向脚本发送消息,或者您的区域设置已被破坏。您应该修复您的环境,而不是将脚本修复到您的环境中,因为这会使脚本非常脆弱

如果是管道,Python假定输出应该是ASCII,并将标准输出的编码设置为ASCII

在正常情况下,Python使用区域设置来确定应用于标准输出的编码。如果您的区域设置被破坏、未安装或损坏,Python将默认为ASCII。一个C语言环境,也会给你一个ASCII编码

通过键入locale检查您的区域设置,并确保没有返回错误。例如

$ locale
LANG="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_CTYPE="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_ALL=
如果所有其他操作都失败或正在进行管道传输,则可以通过设置PythonionEncoding环境变量来覆盖Python的区域设置检测。例如

$ PYTHONIOENCODING=utf-8 ./my_python.sh

请记住,您的shell有一个区域设置,而您的终端有一个编码-它们都需要正确设置

您可能正在向脚本发送管道,或者您的区域设置被破坏。您应该修复您的环境,而不是将脚本修复到您的环境中,因为这会使脚本非常脆弱

如果是管道,Python假定输出应该是ASCII,并将标准输出的编码设置为ASCII

在正常情况下,Python使用区域设置来确定应用于标准输出的编码。如果您的区域设置被破坏、未安装或损坏,Python将默认为ASCII。一个C语言环境,也会给你一个ASCII编码

通过键入locale检查您的区域设置,并确保没有返回错误。例如

$ locale
LANG="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_CTYPE="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_ALL=
如果所有其他操作都失败或正在进行管道传输,则可以通过设置PythonionEncoding环境变量来覆盖Python的区域设置检测。例如

$ PYTHONIOENCODING=utf-8 ./my_python.sh

请记住,shell有一个区域设置,终端有一个编码-它们都需要正确设置

,因为Python 3.7,您可以使用重新配置方法更改写入sys.stdout的所有文本的编码:


如果您需要更改程序所有输出的编码,这可能会很有帮助。

自Python 3.7以来,您可以使用重新配置方法更改写入sys.stdout的所有文本的编码:


如果您需要更改程序中所有输出的编码,这可能会很有帮助。

string_to_print=some_string.decode'utf-8';printstring_to_print do?它只是一个str,所以我得到AttributeError:“str”对象在我的终端中没有属性“decode”,当我执行更多$file时,这些字符显示为问号,所以我的终端可能是ascii。我投票结束这个问题,因为实际的问题太过局部化——它是由错误配置的环境和/或使用引起的,但没有正确描述。string_to_print=some_string。解码“utf-8”;printstring_to_print do?它只是一个str,所以我得到AttributeError:“str”对象在我的终端中没有属性“decode”,当我执行更多$file时,这些字符显示为问号,所以我的终端可能是ascii。我投票结束这个问题,因为实际问题太过局部化——它是由错误配置的环境和/或使用引起的,但没有正确描述。解码后打印只会尝试打印Unicode字符串,这会使您回到开始的位置。你的例子之所以有效,是因为它只包含ASCII字符。是的,同意。必须使用缓冲区写入程序。这对我帮助很大。我从STDIN中读取数据,然后写入一个文件,正如您可以将编码设置为打开,但打印是一个噩梦。如果使用不同的编解码器进行编码和解码,例如printtxt.encodeutf-8.decodecp1252,则结果不完全相同,可能是可打印的。翻译错误实际上有助于找到有问题的字符。解码后打印只会尝试打印Unicode字符串,这会使您回到开始的位置。你的例子之所以有效,是因为它只包含ASCII字符。是的,同意。必须使用缓冲区写入程序。这对我帮助很大。我从一个STDIN读取数据,然后写入一个文件,这样你就可以在open中设置编码了
,但打印是一场噩梦。如果使用不同的编解码器进行编码和解码,例如printtxt.encodeutf-8.decodecp1252,则结果不完全相同,可能是可打印的。翻译错误实际上有助于找到冒犯的字符。这不是管道,但也不是我的环境-这是一个我必须在学校服务器上运行的程序,它有ascii终端。我可以改变我的个人环境或使用不同的终端,但我不能保证评分员会这么做。这是Debian,我正在提交一个.py文件,该文件将由其他计算机上的人使用python3运行,但从相同的文件读取,并始终尝试写入ascii标准。如果你的终端真的是ascii,它们可能不是,为什么您的答案编码为cp1252?我必须编码为cp1252以保持原始数据中的重音标记。此脚本的输出将被重定向到一个文件,我希望该文件具有这些重音符号。我的语言环境没有为LANG/LANGUAGE或ALL设置任何内容,其他所有内容都是POSIX、fwiw1。如果终端显示cp1252,则它们不是ASCII。2如果未定义语言,则环境设置不正确。这就是为什么更多的人失败了。您可能会发现您的学生已经正确配置了环境或不同的编码设置,这意味着您的脆弱代码将不会出现管道,但这也不是我的环境-这是一个我必须在学校服务器上运行的程序,这些服务器具有ascii终端。我可以改变我的个人环境或使用不同的终端,但我不能保证评分员会这么做。这是Debian,我正在提交一个.py文件,该文件将由其他计算机上的人使用python3运行,但从相同的文件读取,并始终尝试写入ascii标准。如果你的终端真的是ascii,它们可能不是,为什么您的答案编码为cp1252?我必须编码为cp1252以保持原始数据中的重音标记。此脚本的输出将被重定向到一个文件,我希望该文件具有这些重音符号。我的语言环境没有为LANG/LANGUAGE或ALL设置任何内容,其他所有内容都是POSIX、fwiw1。如果终端显示cp1252,则它们不是ASCII。2如果未定义语言,则环境设置不正确。这就是为什么更多的人失败了。您可能会发现您的学生已经正确配置了环境或不同的编码设置,这意味着您的脆弱代码将被破坏