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

时间:2012-11-19 11:33:50

标签: 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
)

这让我打印ASCII:

>>> print 'hello'
hello
>>> print u'hello'
hello

但是当我尝试使用非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

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

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

1 个答案:

答案 0 :(得分:1)

试试这个:

# -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    print u'æøå'

交互式python会话中使用 from __future__ import unicode_literals 会很有用。

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

WriteConsoleW有一个我知道的错误,就是它fails when writing more than 26608 characters at once。通过限制一次通话中传递的数据量,可以轻松解决这个问题。

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

(为了完整起见,可以使用Lucida Console和Consolas以外的字体在控制台上显示Unicode,但requires a registry hack。) 我希望它有所帮助。