Python中的Unicode输出';从cmd.exe运行时的标准输出

Python中的Unicode输出';从cmd.exe运行时的标准输出,python,encoding,unicode,utf-8,stdout,Python,Encoding,Unicode,Utf 8,Stdout,我正在运行Windows7,其控制台已配置为使用ConsoleAs字体,这使我有可能输出Unicode。在控制台中读取Unicode的能力已经被我在Far Manager等程序中多次证明:西里尔字母和德文字母都可以在同一控制台上以相同的字符串读取,而无需进行编码切换 现在谈谈Python 我非常努力,但在输出中看不到Unicode。 默认情况下,print(sys.stdout.encoding)printscp866,stdout无法输出ASCII和西里尔字母以外的任何字符 它给了我以下结果:

我正在运行Windows7,其控制台已配置为使用ConsoleAs字体,这使我有可能输出Unicode。在控制台中读取Unicode的能力已经被我在Far Manager等程序中多次证明:西里尔字母和德文字母都可以在同一控制台上以相同的字符串读取,而无需进行编码切换

现在谈谈Python

我非常努力,但在输出中看不到Unicode。 默认情况下,
print(sys.stdout.encoding)
prints
cp866
,stdout无法输出ASCII和西里尔字母以外的任何字符

它给了我以下结果:

print(“ЛääÄääÜß”)

UnicodeEncodeError:“charmap”编解码器无法对位置6-12中的字符进行编码:字符映射到

打印(“utf-8”)

b'\xd0\x9b\xd1\x8f-\xd0\xbb\xd1\x8f\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f'

好的,我已经在批处理文件中设置了
pythonionecoding
环境变量:

SET pythonionecoding=UTF-8

得到:

print(sys.stdout.encoding)
UTF-8

print("Ля-ля äöüÄÖÜß")
╨Ы╤П-╨╗╤П ├д├╢├╝├Д├Ц├Ь├Я

print("Ля-ля äöüÄÖÜß".encode("utf-8"))`
b'\xd0\x9b\xd1\x8f-\xd0\xbb\xd1\x8f \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f'

怎么办?

事实上,Python和Windows控制台之间的交互存在某种缺陷(请参阅)。可以使用C函数ReadConsoleW、WriteConsoleW而不是ReadConsole和WriteConsole在Windows控制台中读写Unicode。所以,一个可行的解决方案是编写自己的stdout和stdin对象,通过ctypes调用ReadConsoleW和WriteConsoleW。对于输出,这是可行的,但是对于输入,有一个问题是Python交互式解释器实际上不使用sys.stdin来获取输入(但是调用input()函数是可行的)——请参阅

很多人说Windows控制台有问题。但实际上,您可以毫无问题地键入Unicode字符(如果您有适当的键盘布局)。这些显示没有问题。您甚至可以运行名为“∫.py”和一些Unicode参数,并且它正确运行,并且参数在sys.argv字符串中正确等待


更新:我构建了一个Python包来处理这些问题。见和。通过
pip安装win\u unicode\u控制台安装
。至少对我来说,它在Python3.4、Python3.5和Python2.7上工作。

事实上,Python和Windows控制台之间的交互存在某种缺陷(请参阅)。可以使用C函数ReadConsoleW、WriteConsoleW而不是ReadConsole和WriteConsole在Windows控制台中读写Unicode。所以,一个可行的解决方案是编写自己的stdout和stdin对象,通过ctypes调用ReadConsoleW和WriteConsoleW。对于输出,这是可行的,但是对于输入,有一个问题是Python交互式解释器实际上不使用sys.stdin来获取输入(但是调用input()函数是可行的)——请参阅

很多人说Windows控制台有问题。但实际上,您可以毫无问题地键入Unicode字符(如果您有适当的键盘布局)。这些显示没有问题。您甚至可以运行名为“∫.py”和一些Unicode参数,并且它正确运行,并且参数在sys.argv字符串中正确等待


更新:我构建了一个Python包来处理这些问题。见和。通过
pip安装win\u unicode\u控制台安装
。至少对我来说,它在Python 3.4、Python 3.5和Python 2.7上是有效的。

众所周知,Windows控制台很难将更高的unicode码点值打印到其中。@Martijn Pieters:我不确定您称之为“更高的码点”值是什么。我需要至少俄语和德语,Windows console证明了它可以做到。问题是你的控制台代码页需要切换,但微软提供的唯一代码页是cp65001;他们对UTF-8的想法充满了错误。参见示例。我使用术语“更高的码点unicode值”来区分ASCII和拉丁1码点;令人惊讶的是,有很多人不将其视为Unicode或出于某种原因。众所周知,Windows控制台很难将更高的Unicode代码点值打印到其中。@Martijn Pieters:我不确定您称之为“更高的代码点”值是什么。我需要至少俄语和德语,Windows console证明了它可以做到。问题是你的控制台代码页需要切换,但微软提供的唯一代码页是cp65001;他们对UTF-8的想法充满了错误。参见示例。我使用术语“更高的码点unicode值”来区分ASCII和拉丁1码点;令人惊讶的是,有很多人不把这些数字算作Unicode或其他原因。这个错误已经在2007-12-12提交,但仍然没有解决方案!!!该漏洞已提交至2007-12-12,但仍然没有解决方案!!!