Python 3.0, как сделать print() вывод unicode?

Я работаю в WinXP 5.1.2600, пишу приложение Python с участием китайского пиньинь, которое вовлекло меня в бесконечные проблемы Unicode. Переключение на Python 3.0 решило многие из них. Но функция print() для вывода консоли не относится к Unicode по какой-то нечетной причине. Вот детская программа.

print('sys.stdout encoding is "' + sys.stdout.encoding + '"')
str1 = 'lüelā'
print(str1)

Выход (изменение угловых скобок в квадратных скобках для удобства чтения):

    sys.stdout encoding is "cp1252"
    Traceback (most recent call last):
      File "TestPrintEncoding.py", line 22, in [module]
        print(str1)
      File "C:\Python30\lib\io.py", line 1491, in write
        b = encoder.encode(s)
      File "C:\Python30\lib\encodings\cp1252.py", line 19, in encode
        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
    UnicodeEncodeError: 'charmap' codec can't encode character '\u0101' 
    in position 4: character maps to [undefined]

Обратите внимание, что ü =\xfc = 252 не вызывает проблем, так как это верхний ASCII. Но ā =\u0101 превышает 8 бит.

У кого-нибудь есть идея, как изменить кодировку sys.stdout на "utf-8"? Имейте в виду, что Python 3.0 больше не использует модуль codecs, если я правильно понимаю документацию.


Извиняюсь, я дал вам программу без преамбулы. Перед заданием трех строк он начинается следующим образом:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

К сожалению, кодирование, указанное строкой "кодирование:", - это кодирование исходного кода, а не выход на консоль. Но спасибо за ваши мысли!

Ответ 1

Командная строка Windows (cmd.exe) не может отображать символы Unicode, которые вы используете, хотя Python обрабатывает ее правильным образом. Вам нужно использовать IDLE, Cygwin или другую программу, которая может правильно отображать Unicode.

См. эту тему для полного объяснения: http://www.nabble.com/unable-to-print-Unicode-characters-in-Python-3-td21670662.html

Ответ 2

Вы можете попробовать изменить переменную среды "PYTHONIOENCODING" на "utf_8". С этой проблемой я написал страницу .

Ответ 3

Посмотрите вопрос и ответ здесь, я думаю, что у них есть ценные подсказки. В частности, обратите внимание на setdefaultencoding в модуле sys, но также и тот факт, что вы, вероятно, не должны его использовать.

Ответ 4

Известна проблема отображения символов Unicode в Python в Windows. Официального решения пока нет. Правильная вещь - использовать функцию winapi WriteConsoleW. Нетрудно построить рабочее решение, так как есть другие связанные проблемы. Однако я разработал пакет, который пытается исправить Python по этой проблеме. См. https://github.com/Drekin/win-unicode-console. Вы также можете прочитать там более глубокое объяснение проблемы. Пакет также находится на pypi (https://pypi.python.org/pypi/win_unicode_console) и может быть установлен с помощью pip.

Ответ 5

Вот грязный хак:

# works
import os
os.system("chcp 65001 &")
print("юникод")

Однако все это сломает:

  • простая первая заглушающая строка уже разбивает ее:

    # doesn't work
    import os
    os.system("chcp 65001 >nul &")
    print("юникод")
    
  • проверка типа ОС прерывает его:

    # doesn't work
    import os
    if os.name == "nt":
        os.system("chcp 65001 &")
    
    print("юникод")
    
  • он даже не работает в if block:

    # doesn't work
    import os
    if os.name == "nt":
        os.system("chcp 65001 &")
        print("юникод")
    

Но можно печатать с помощью cmd echo:

# works
import os
os.system("chcp 65001 & echo {0}".format("юникод"))

и вот простой способ сделать эту кросс-платформу:

# works

import os

def simple_cross_platrofm_print(obj):
    if os.name == "nt":
        os.system("chcp 65001 >nul & echo {0}".format(obj))
    else:
        print(obj)

simple_cross_platrofm_print("юникод")

но окно echo завершающая пустая строка не может быть подавлена.