Как обстоят дела с Python 3.4, Unicode, различными языками и Windows?
Счастливые примеры:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
czech = u'Leoš Janáček'.encode("utf-8")
print(czech)
pl = u'Zdzisław Beksiński'.encode("utf-8")
print(pl)
jp = u'リング 山村 貞子'.encode("utf-8")
print(jp)
chinese = u'五行'.encode("utf-8")
print(chinese)
MIR = u'Машина для Инженерных Расчётов'.encode("utf-8")
print(MIR)
pt = u'Minha Língua Portuguesa: çáà'.encode("utf-8")
print(pt)
Несчастный вывод:
b'Leo\xc5\xa1 Jan\xc3\xa1\xc4\x8dek'
b'Zdzis\xc5\x82aw Beksi\xc5\x84ski'
b'\xe3\x83\xaa\xe3\x83\xb3\xe3\x82\xb0 \xe5\xb1\xb1\xe6\x9d\x91 \xe8\xb2\x9e\xe5\xad\x90'
b'\xe4\xba\x94\xe8\xa1\x8c'
b'\xd0\x9c\xd0\xb0\xd1\x88\xd0\xb8\xd0\xbd\xd0\xb0 \xd0\xb4\xd0\xbb\xd1\x8f \xd0\x98\xd0\xbd\xd0\xb6\xd0\xb5\xd0\xbd\xd0\xb5\xd1\x80\xd0\xbd\xd1\x8b\xd1\x85 \xd0\xa0\xd0\xb0\xd1\x81\xd1\x87\xd1\x91\xd1\x82\xd0\xbe\xd0\xb2'
b'Minha L\xc3\xadngua Portuguesa: \xc3\xa7\xc3\xa1\xc3\xa0'
И если я напечатаю их так:
jp = u'リング 山村 貞子'
print(jp)
Я получил:
Traceback (most recent call last):
File "x.py", line 5, in <module>
print(jp)
File "C:\Python34\lib\encodings\cp850.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position
0-2: character maps to <undefined>
Я также попробовал следующее из этого вопроса (И другие альтернативы, которые включают sys.stdout.encoding
):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys
def safeprint(s):
try:
print(s)
except UnicodeEncodeError:
if sys.version_info >= (3,):
print(s.encode('utf8').decode(sys.stdout.encoding))
else:
print(s.encode('utf8'))
jp = u'リング 山村 貞子'
safeprint(jp)
И все становится еще более загадочным:
リング 山村 貞子
И документы были не очень полезны.
Итак, как обстоят дела с Python 3.4, Unicode, различными языками и Windows? Почти все возможные примеры, которые я смог найти, касаются Python 2.x.
Существует ли общий и кроссплатформенный способ печати ЛЮБОГО символа Unicode с любого языка достойным и не противным способом в Python 3.4?
РЕДАКТИРОВАТЬ:
Я попытался набрать в терминале:
chcp 65001
Изменить кодовую страницу, как предложено здесь и в комментариях, так и не получилось (включая попытку с sys.stdout.encoding)
2 ответа
Проблема была (см. Обновление Python 3.6 ниже) с консолью Windows, которая поддерживает набор символов ANSI, соответствующий региону, на который ориентирована ваша версия Windows. Python генерирует исключение по умолчанию, когда выводятся неподдерживаемые символы.
Python может читать переменную окружения для вывода в других кодировках или для изменения значения по умолчанию при обработке ошибок. Ниже я прочитал консоль по умолчанию и изменил обработку ошибок по умолчанию для печати ?
вместо того, чтобы выдавать ошибку для символов, которые не поддерживаются в текущей кодовой странице консоли.
C:\>chcp
Active code page: 437 # Note, US Windows OEM code page.
C:\>set PYTHONIOENCODING=437:replace
C:\>example.py
Leo? Janá?ek
Zdzis?aw Beksi?ski
??? ?? ??
??
?????? ??? ?????????? ????????
Minha Língua Portuguesa: çáà
Обратите внимание, что кодовая страница OEM-производителя в США ограничена символами ASCII и некоторыми символами Западной Европы.
Ниже я дал указание Python использовать UTF8, но поскольку консоль Windows не поддерживает его, я перенаправляю вывод в файл и отображаю его в блокноте:
C:\>set PYTHONIOENCODING=utf8
C:\>example >out.txt
C:\>notepad out.txt
В Windows лучше всего использовать Python IDE, которая поддерживает UTF-8 вместо консоли, при работе с несколькими языками. Если используется только один язык, выберите его в качестве локали системы в Region and Language
Панель управления и консоль будут поддерживать символы этого языка.
Обновление для Python 3.6
Python 3.6 теперь использует API-интерфейсы Windows Unicode для прямой записи в консоль, поэтому единственным ограничением является поддержка символов шрифта консоли. Следующий код работает в консоли Windows для США. У меня установлен китайский языковой пакет, он даже отображает китайский и японский языки, если изменить шрифт консоли. Даже без правильного шрифта символы замены отображаются в консоли. Cut-n-paste для среды, такой как эта веб-страница, будет правильно отображать символы.
#!python3.6
#coding: utf8
czech = 'Leoš Janáček'
print(czech)
pl = 'Zdzisław Beksiński'
print(pl)
jp = 'リング 山村 貞子'
print(jp)
chinese = '五行'
print(chinese)
MIR = 'Машина для Инженерных Расчётов'
print(MIR)
pt = 'Minha Língua Portuguesa: çáà'
print(pt)
Выход:
Leoš Janáček
Zdzisław Beksiński
リング 山村 貞子
五行
Машина для Инженерных Расчётов
Minha Língua Portuguesa: çáà
Обновление: начиная с Python 3.6, пример кода, который печатает строки Unicode напрямую, теперь должен работать (даже без py -mrun
)
Python может печатать текст на нескольких языках в консоли Windows независимо chcp
говорит:
T:\> py -mpip install win-unicode-console
T:\> py -mrun your_script.py
где your_script.py
печатает Unicode напрямую, например:
#!/usr/bin/env python3
print('š áč') # cz
print('ł ń') # pl
print('リング') # jp
print('五行') # cn
print('ш я жх ё') # ru
print('í çáà') # pt
Все, что вам нужно, это настроить шрифт в консоли Windows, который может отображать нужные символы.
Вы также можете запустить скрипт Python через IDLE, не устанавливая не-stdlib модули:
T:\> py -midlelib -r your_script.py
Чтобы записать в файл / канал, используйте PYTHONIOENCODING=utf-8
как @Mark Tolonen предложил:
T:\> set PYTHONIOENCODING=utf-8
T:\> py your_script.py >output-utf8.txt
Только последнее решение поддерживает символы не-BMP, такие как (U + 1F612 UNAMUSED FACE) - py -mrun
Можно написать их, но консоль Windows отображает их в виде блоков, даже если шрифт поддерживает соответствующие символы Unicode (хотя вы можете скопировать и вставить поля в другую программу, чтобы получить символы).