Подтвердить что ты не робот

Почему я получаю IOErrors при записи Unicode в CMD? (С кодовой страницей 65001)

Я на CMD в Windows 8, и я установил кодовую страницу до 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

Но ошибки, которые я получаю, когда пытаюсь напечатать строку Unicode с символами, отличными от ASCII, не имеют для меня никакого смысла. Здесь я пытаюсь напечатать несколько строк, содержащих скандинавские символы (я добавил дополнительный разрыв строки между отпечатками для удобочитаемости):

>>> 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

Как вы видите, это не всегда вызывает ошибку (и даже не вызывает такую ​​же ошибку каждый раз), а скандинавские символы отображаются только иногда.

Может кто-нибудь объяснить это поведение или, по крайней мере, помочь мне разобраться, как правильно печатать Юникод в CMD?

4b9b3361

Ответ 1

Попробуйте следующее:

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

Использование из __future__ import unicode_literals было бы полезно в интерактивном сеансе python.

Конечно, можно успешно использовать Unicode для консоли, используя WriteConsoleW. Это работает независимо от кодовой страницы консоли, включая 65001. Код здесь делает это (это для Python 2.x, но вы бы вызывая WriteConsoleW от C в любом случае).

WriteConsoleW имеет одну ошибку, о которой я знаю, что она не работает при записи более 26608 символов. Это легко обойти, ограничив количество данных, переданных за один вызов.

Шрифты не являются проблемой Python, но кодировка. Не имеет смысла выводить правильные символы только потому, что некоторые пользователи могут не выбирать шрифты, которые могут отображать эти символы. Эта ошибка должна быть вновь открыта.

(Для полноты можно отобразить Unicode на консоли, используя шрифты, отличные от Lucida Console и Consolas, но требует взлома реестра). Надеюсь, это поможет.