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

Hub*_*bro 12 python windows windows-8

我在Windows 8中使用CMD,并且我将代码页设置为65001(chcp 65001).我使用的是Python 2.7.2(ActivePython 2.7.2.5),我将PYTHONSTARTUP环境变量设置为"bootstrap.py".

bootstrap.py:

import codecs
codecs.register(
    lambda name: name == 'cp65001' and codecs.lookup('UTF-8') or None
)
Run Code Online (Sandbox Code Playgroud)

这让我打印ASCII:

>>> print 'hello'
hello
>>> print u'hello'
hello
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用非ASCII字符打印Unicode字符串时得到的错误对我来说毫无意义.在这里,我尝试打印一些包含北欧符号的字符串(为了便于阅读,我在打印件之间添加了额外的换行符):

>>> print u'æøå'
??øåTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory

>>> print u'åndalsnes'
??ndalsnes

>>> print u'åndalsnesæ'
??ndalsnesæTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument

>>> print u'Øst'
??st

>>> print u'uØst'
uØstTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument

>>> print u'ØstÆØÅæøå'
??stÆØÅæøåTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument

>>> print u'_ØstÆØÅæøå'
_ØstÆØÅæøåTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument
Run Code Online (Sandbox Code Playgroud)

如您所见,它并不总是引发错误(并且每次都不会引发相同的错误),并且偶尔会正确显示Nordic符号.

有人可以解释这种行为,或者至少帮助我弄清楚如何正确地将Unicode打印到CMD?

Soh*_*eil 1

尝试这个 :

\n\n
# -*- coding: utf-8 -*-\n    from __future__ import unicode_literals\n    print u\'\xc3\xa6\xc3\xb8\xc3\xa5\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

在交互式 Python 会话中,使用 from __future__ import unicode_literals将非常有用。

\n\n

当然可以使用WriteConsoleW成功地将 Unicode 写入控制台无论控制台代码页如何,包括 65001,这都有效。这里的代码就是这样做的(它适用于 Python 2.x,但无论如何你都会从 C 调用 WriteConsoleW)。

\n\n

据我所知,WriteConsoleW 有一个错误,即一次写入超过 26608 个字符时会失败。通过限制单个调用中传递的数据量,很容易解决这个问题。

\n\n

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

\n\n

(为了完整起见,可以使用 Lucida Console 和 Consolas 以外的字体在控制台上显示 Unicode,但它需要注册表破解。)\n我希望它有所帮助。

\n