Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么在将Unicode写入CMD时会出现IOErrors?(带代码页65001)_Python_Windows_Windows 8 - Fatal编程技术网

Python 为什么在将Unicode写入CMD时会出现IOErrors?(带代码页65001)

Python 为什么在将Unicode写入CMD时会出现IOErrors?(带代码页65001),python,windows,windows-8,Python,Windows,Windows 8,我在Windows 8中的CMD上,我已将代码页设置为65001(chcp 65001)。我使用的是Python2.7.2(ActivePython2.7.2.5),我已经将PYTHONSTARTUP环境变量设置为“bootstrap.py” bootstrap.py: import codecs codecs.register( lambda name: name == 'cp65001' and codecs.lookup('UTF-8') or None ) 这使我可以打印ASC

我在Windows 8中的CMD上,我已将代码页设置为65001(
chcp 65001
)。我使用的是Python2.7.2(ActivePython2.7.2.5),我已经将PYTHONSTARTUP环境变量设置为“bootstrap.py”

bootstrap.py:

import codecs
codecs.register(
    lambda name: name == 'cp65001' and codecs.lookup('UTF-8') or None
)
这使我可以打印ASCII:

>>> print 'hello'
hello
>>> print u'hello'
hello
但是,当我试图打印带有非ASCII字符的Unicode字符串时,我遇到的错误对我来说毫无意义。在这里,我尝试打印几个包含北欧符号的字符串(为了可读性,我在打印之间添加了额外的换行符):

>>打印u'æå'
��øå回溯(最近一次呼叫最后一次):
文件“”,第1行,在
IOError:[Errno 2]没有这样的文件或目录
>>>打印u'ndalsnes'
��翁达尔斯内斯
>>>打印u'ndalsnes'
��ndalsnesæ回溯(最近一次呼叫最后一次):
文件“”,第1行,在
IOError:[Errno 22]参数无效
>>>打印uØst'
��圣
>>>打印u'uØst'
uØstTraceback(最近一次呼叫最后一次):
文件“”,第1行,在
IOError:[Errno 22]参数无效
>>>打印u'stÆØæå'
��stÆØæå回溯(最近一次呼叫最后一次):
文件“”,第1行,在
IOError:[Errno 22]参数无效
>>>打印u“stÆØØæå”
_ØstÆØØæå回溯(最近一次呼叫最后一次):
文件“”,第1行,在
IOError:[Errno 22]参数无效
正如您所看到的,它并不总是引发错误(甚至不是每次都引发相同的错误),北欧符号只是偶尔正确显示

谁能解释一下这种行为,或者至少帮我弄清楚如何将Unicode正确地打印到CMD中吗?

试试这个:

# -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    print u'æøå'
在交互式python会话中,使用来自未来导入unicode文本的将非常有用

当然可以使用WriteConsoleW成功地将Unicode写入控制台。无论控制台代码页(包括65001)如何,此功能都有效。代码就是这样做的(它是针对Python2.x的,但无论如何都要从C调用WriteConsoleW)

WriteConsoleW有一个我知道的bug,就是它。通过限制单个调用中传递的数据量,这很容易解决

字体不是Python的问题,但编码是。仅仅因为某些用户可能没有选择可以显示这些字符的字体,所以无法输出正确的字符是没有意义的。应该重新打开此错误

(为了完整性,可以使用Lucida console和ConsoleAs以外的字体在控制台上显示Unicode,但不需要。)
我希望这会有帮助。

这是一个噩梦般的情况。在这里和其他地方已经讨论过无数次了。例如:@DavidHeffernan:我已经查看了搜索结果,我能找到的最接近标准答案是OP已经在做的事情。在我看来,要么这是一个新的变体,要么这个问题从未真正得到正确的回答?至少3.3中改进了对Windows代码页的支持:。后者由
编解码器使用。code\u page\u encode
,新的cp65001编解码器使用它来定义
encode=functools。partial(codec.code\u page\u encode,65001)
,以及类似的解码功能。当前
打印项
op调用
PyFile\u WriteObject
,调用
PyObject\u PRINT
,它最终调用
PyString\u Type.tp\u print
,它使用libc
fwrite
写入标准输出。问题在于一个错误,它导致stdout
文件
流设置了错误标志,即使没有发生错误(因此报告了随机“错误”),因为
write
返回写入的字符数而不是字节数。您可以使用
os.write(sys.stdout.fileno(),s)
来验证这一点,其中
s
是非ASCII UTF-8字符串。这在Python 3中不是问题,因为它实现了自己的缓冲(
\u io.BufferedWriter
),底层的
\u io.FileIO
对目标文件描述符执行低级
写入操作。我认为WriteConsoleW仅限于UCS-2,即不能使用补充平面中的字符。但在大多数情况下,这不应该是一个问题。
# -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    print u'æøå'