Pytanie O co chodzi z Pythonem 3.4, Unicode, różnymi językami i Windows?


Szczęśliwe przykłady:

#!/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)

Niezadowalające wyniki:

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'

A jeśli wydrukuję je w ten sposób:

jp = u'リング 山村 貞子'
print(jp)

Dostaję:

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>

Próbowałem również następujące to pytanie (I inne alternatywy, które obejmują 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)

A sprawy stają się jeszcze bardziej zagadkowe:

リング 山村 貞子

A dokumenty nie były zbyt pomocne.

O co chodzi z Pythonem 3.4, Unicode, różnymi językami i Windows? Prawie wszystkie możliwe przykłady, jakie mogłem znaleźć, radzą sobie z Pythonem 2.x.

Czy istnieje ogólny i wieloplatformowy sposób drukowania dowolnej postaci Unicode z dowolnego języka w przyzwoity i nieprzyjemny sposób w Pythonie 3.4?

EDYTOWAĆ:

Próbowałem pisać na terminalu:

chcp 65001

Aby zmienić stronę kodową, zgodnie z propozycją tutaj i w komentarzach, i to nie zadziałało (włączając próbę z sys.stdout.encoding)


21
2018-05-29 22:14


pochodzenie


python3 wydrukuj kod Unicode do konsoli Windows xp kodowania cp437 wygląda tak, jak ma to zastosowanie python 3.0, jak sprawić, aby print () wyprowadził kod Unicode?. - Martijn Pieters♦
Twoja konsola nie jest skonfigurowana do wyjścia Unicode; CP850 nie poradzę sobie tak bardzo. - Martijn Pieters♦
Myślę, że problem nie występuje w Pythonie, ale w konsoli Windows, która będzie miała tylko jedną stronę kodową, która domyślnie nie jest unikodowa. Próbować chcp 65001 aby ustawić go na stronie kodowej UTF-8. Pochodzi z Znaki Unicode w wierszu poleceń systemu Windows. - GolezTrol
Spodziewam się dostać to samo, co włożyłem w struny. - Ericson Willians
Konsola systemu Windows może drukować ciągi Unicode dobrze (zakładając, że czcionka obsługuje to), używając WriteConsoleW. Ale Python tego nie używa, patrz bugs.python.org/issue1602. - Philipp


Odpowiedzi:


Problem jestbył (patrz aktualizacja Pythona 3.6 poniżej) z konsolą Windows, która obsługuje zestaw znaków ANSI odpowiedni dla regionu, na który skierowana jest twoja wersja systemu Windows. Python generuje wyjątek domyślnie, gdy wyprowadzane są nieobsługiwane znaki.

Python może czytać Zmienna środowiskowa do wyprowadzania w innych kodowaniach lub do zmiany domyślnej obsługi błędów. Poniżej przeczytałem domyślną konsolę i zmieniłem domyślną obsługę błędów, aby wydrukować ? zamiast rzucać błąd dla znaków, które nie są obsługiwane na aktualnej stronie kodowej konsoli.

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: çáà

Uwaga: strona kodowa OEM OEM jest ograniczona do znaków ASCII i niektórych znaków z Europy Zachodniej.

Poniżej poleciłem Pythonowi używanie UTF8, ale ponieważ konsola systemu Windows go nie obsługuje, przekierowuję dane wyjściowe do pliku i wyświetlam go w Notatniku:

C:\>set PYTHONIOENCODING=utf8
C:\>example >out.txt
C:\>notepad out.txt

enter image description here

W systemie Windows najlepiej jest używać IDE Pythona, który obsługuje UTF-8 zamiast konsoli podczas pracy z wieloma językami. Jeśli używasz tylko jednego języka, wybierz go jako ustawienia regionalne systemu Region and Language Panel sterowania i konsola obsługują znaki tego języka.

Aktualizacja dla Python 3.6

Python 3.6 korzysta teraz z interfejsów API systemu Windows Unicode, aby pisać bezpośrednio na konsoli, więc jedynym ograniczeniem jest obsługa czcionek konsoli przez znaki. Poniższy kod działa w amerykańskiej konsoli systemu Windows. Mam zainstalowany chiński pakiet językowy, wyświetla on nawet chiński i japoński, jeśli zmieni się czcionka konsoli. Nawet bez poprawnej czcionki znaki zastępcze są wyświetlane w konsoli. Wytnij-wklej do środowiska takiego jak ta strona internetowa wyświetli znaki poprawnie.

#!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)

Wydajność:

Leoš Janáček
Zdzisław Beksiński
リング 山村 貞子
五行
Машина для Инженерных Расчётов
Minha Língua Portuguesa: çáà

10
2018-05-29 23:19



Konsola systemu Windows może drukować dowolne ciągi Unicode za pomocą WriteConsoleW (ograniczone przez obsługę czcionek i niepoprawne traktowanie znaków spoza BMP). Python nie używa tej funkcji; widzieć bugs.python.org/issue1602 dla jakiejś dyskusji. - Philipp
Python 3.6: musisz skonfigurować konsolę: kliknij prawym przyciskiem myszy w górnej części okna (z cmd lub pytla IDLE), w domyślnej / czcionce wybierz "konsolę Lucidy". - JinSnow
@Guillaume To nie pomoże chińskim / japońskim. Zainstalowałem pakiet języka chińskiego w systemie Windows 10, a następnie dostępne były nowe czcionki konsoli. Czcionki SimSun wyglądały dobrze i obsługiwały wszystkie sześć powyższych języków. - Mark Tolonen
@MarkTolonen dzięki za wyjaśnienie! - JinSnow


Aktualizacja:  Od wersji Python 3.6 przykład kodu, który bezpośrednio drukuje ciągi Unicode, powinien działać teraz (nawet bez) py -mrun).


Python może drukować tekst w wielu językach na konsoli Windows, niezależnie od tego chcp mówi:

T:\> py -mpip install win-unicode-console
T:\> py -mrun your_script.py

gdzie your_script.py drukuje Unicode bezpośrednio np .:

#!/usr/bin/env python3
print('š áč')      # cz
print('ł ń')       # pl
print('リング')     # jp
print('五行')      # cn
print('ш я жх ё') # ru
print('í çáà')    # pt

Wystarczy skonfigurować czcionkę w konsoli systemu Windows, która może wyświetlać żądane znaki.

Możesz również uruchomić skrypt Pythona przez IDLE bez instalowania modułów non-stdlib:

T:\> py -midlelib -r your_script.py

Aby napisać do pliku / potoku, użyj PYTHONIOENCODING=utf-8 tak jak @Mark Tolonen zasugerował:

T:\> set PYTHONIOENCODING=utf-8
T:\> py your_script.py >output-utf8.txt 

Tylko ostatnie rozwiązanie obsługuje znaki inne niż BMP, takie jak  (U + 1F612 UNAMUSED FACE) - py -mrun można je zapisać, ale konsola systemu Windows wyświetla je jako pola, nawet jeśli czcionka obsługuje odpowiednie znaki Unicode (można jednak skopiować i wkleić te pola do innego programu, aby uzyskać znaki).


18
2018-05-30 21:26



Jak byś zrobił interaktywne wersje? Domyślam się, że Python jest python -i -m run, ale nie mogę wymyślić ipython, mimo że na stronie win-unicode-console jest napisane, że jest zintegrowane. - hyperknot
@zsero: dokumenty pokazują kilka podejść na przykład., py -i -m run c:\path\to\ipython. Możesz także użyć interfejsu qtconsole lub notatnik oparty na przeglądarce internetowej. Jeśli to nie działa dla ciebie; zadaj osobne pytanie o to, co chcesz zrobić ipython i co nie udaje się dokładnie. - jfs
@eryksun: nie. Zauważ, że py -mrun Jest używane. - jfs
@Ssebastian Myślę, że rozwiązałem mój problem z twoją pomocą. Twoja odpowiedź jest bite mylące: jako użytkownik python 3.6 nie zrozumiałem, czy powinienem zignorować lub wziąć pod uwagę to, co piszesz poniżej. Jeśli tak jest, rodzaj "dla poprzedniej wersji:" uczyniłby to bardziej zrozumiałym. Dziękuję za cierpliwość! - JinSnow
Konsola Lucidy również nie obsługuje języka chińskiego ani japońskiego. - Mark Tolonen