Kiedy próbuję wydrukować ciąg Unicode w konsoli systemu Windows, pojawia się UnicodeEncodeError: 'charmap' codec can't encode character ....
błąd. Zakładam, że dzieje się tak, ponieważ konsola systemu Windows nie akceptuje znaków tylko w Unicode. Jaki jest najlepszy sposób obejścia tego? Czy jest jakiś sposób, żebym mógł sprawić, by Python automatycznie drukował ?
zamiast niepowodzenia w tej sytuacji?
Edycja: używam Pythona 2.5.
Uwaga: odpowiedź @ LasseV.Karlsen ze znacznikiem wyboru jest nieco nieaktualna (od 2008 r.). Prosimy o ostrożne korzystanie z poniższych rozwiązań / odpowiedzi / sugestii !!
Odpowiedź @JFSebastian jest bardziej aktualna na dzień dzisiejszy (6 stycznia 2016 r.).
Odpowiedzi:
Uwaga: ta odpowiedź jest nieco nieaktualna (od 2008 r.). Proszę ostrożnie korzystać z poniższego rozwiązania !!
Oto strona, która szczegółowo opisuje problem i rozwiązanie (wyszukaj na stronie tekst Wrapping sys.stdout into an instance ):
PrintFails - Python Wiki
Oto fragment kodu z tej strony:
Na tej stronie jest więcej informacji, które warto przeczytać.
źródło
sys.stdout
, drukuje niewłaściwe rzeczy. Na przykład,u'\u2013'
staje sięû
zamiast półpauzu.cp437
różni się od strony kodowej Windows ANSI, takiej jakcp1252
. Kod nie naprawiaUnicodeEncodeError: 'charmap' codec can't encode character
błędu i może prowadzić np. Do mojibake'a,ا©
jest po cichu zastępowany przez╪º⌐
.Aktualizacja: Python 3.6 implementuje PEP 528: Zmień kodowanie konsoli systemu Windows na UTF-8 : domyślna konsola w systemie Windows będzie teraz akceptować wszystkie znaki Unicode. Wewnętrznie używa tego samego API Unicode jak na
win-unicode-console
opakowaniu wymienionym poniżej .print(unicode_string)
powinno teraz działać.Ten błąd oznacza, że znaki Unicode, które próbujesz wydrukować, nie mogą być reprezentowane przy użyciu bieżącego
chcp
kodowania znaków konsoli. Strona kodowa jest częstocp437
kodowana 8-bitowo, na przykład może reprezentować tylko ~ 0x100 znaków z ~ 1 M znaków Unicode:Konsola systemu Windows akceptuje znaki Unicode, a nawet może je wyświetlać (tylko BMP), jeśli skonfigurowano odpowiednią czcionkę .
WriteConsoleW()
API należy używać zgodnie z sugestią zawartą w odpowiedzi @Daira Hopwood . Można to nazwać transparentnie, tzn. Nie musisz i nie powinieneś modyfikować swoich skryptów, jeśli używaszwin-unicode-console
pakietu :Zobacz O co chodzi z Pythonem 3.4, Unicode, różnymi językami i systemem Windows?
Jeśli
?
w twoim przypadku wystarczy zamienić wszystkie niekodowalne znaki na, możesz ustawićPYTHONIOENCODING
envvar :W Pythonie
PYTHONIOENCODING
3.6+ kodowanie określone przez envvar jest ignorowane dla buforów konsoli interaktywnej, chyba żePYTHONLEGACYWINDOWSIOENCODING
envvar jest ustawiony na niepusty ciąg.źródło
print('\u4E01')
,print('\u6b63')
).Pomimo innych wiarygodnie brzmiących odpowiedzi, które sugerują zmianę strony kodowej na 65001, to nie działa . (Również, zmieniając domyślne kodowanie za pomocą
sys.setdefaultencoding
to nie jest dobry pomysł ).Zobacz to pytanie, aby uzyskać szczegółowe informacje i kod, który działa.
źródło
win-unicode-console
Pakiet Pythona (oparty na Twoim kodzie) pozwala uniknąć modyfikacji skryptu, jeśli drukuje on Unicode bezpośrednio za pomocąpy -mrun your_script.py
polecenia .Jeśli nie jesteś zainteresowany uzyskaniem wiarygodnej reprezentacji złych znaków, możesz użyć czegoś takiego (praca z pythonem> = 2.6, w tym 3.x):
Złe znaki w ciągu zostaną przekonwertowane na reprezentację, którą można wydrukować w konsoli systemu Windows.
źródło
.encode('utf8').decode(sys.stdout.encoding)
prowadzi do mojibake, np.u"\N{EM DASH}".encode('utf-8').decode('cp437')
->ΓÇö
print(s.encode('utf-8'))
może być lepszym sposobem uniknięcia błędów kompilatora. Zamiast tego otrzymujesz wyjście \ xNN dla niedrukowalnych znaków, co wystarczyło dla moich komunikatów diagnostycznych.Poniższy kod spowoduje, że dane wyjściowe Pythona będą wyświetlane na konsoli jako UTF-8 nawet w systemie Windows.
Konsola będzie dobrze wyświetlać znaki w systemie Windows 7, ale w systemie Windows XP nie będzie ich dobrze wyświetlać, ale przynajmniej będzie działać i co najważniejsze, będziesz mieć spójne dane wyjściowe ze skryptu na wszystkich platformach. Będziesz mógł przekierować dane wyjściowe do pliku.
Poniższy kod został przetestowany w Pythonie 2.6 w systemie Windows.
źródło
import win32console
zewnątrz a,try
a później warunkowo wewnątrz atry
? Czy to nie jest bezcelowe (pierwszeimport
)Po prostu wprowadź ten kod w linii poleceń przed wykonaniem skryptu w Pythonie:
źródło
Podobnie jak odpowiedź Giampaolo Rodolà, ale jeszcze bardziej brudna: naprawdę, naprawdę zamierzam spędzić dużo czasu (wkrótce) na zrozumieniu całego tematu kodowań i ich zastosowania w konsolach Windoze,
W tej chwili chciałem tylko sthg, co oznaczałoby, że mój program NIE ulegnie awarii i co zrozumiałem ... a także nie wymagało importowania zbyt wielu egzotycznych modułów (w szczególności używam Jythona, więc przez połowę czasu Python okazuje się, że w rzeczywistości nie jest dostępny).
Uwaga: "pr" jest krótsze niż "print" (i trochę krótsze niż "safeprint") ...!
źródło
W przypadku Pythona 2 wypróbuj:
W przypadku Pythona 3 wypróbuj:
Lub wypróbuj win-unicode-console:
źródło
TL; DR:
Sam napotkałem to, pracując nad botem do czatu na Twitchu (IRC). (Najnowszy Python 2.7)
Chciałem przeanalizować wiadomości na czacie, aby odpowiedzieć ...
ale także bezpiecznie wydrukuj je na konsoli w formacie czytelnym dla człowieka:
To rozwiązało problem z wyrzucaniem przez bota
UnicodeEncodeError: 'charmap'
błędów i zastąpiło znaki Unicode na?
.źródło
Przyczyną twojego problemu NIE jest konsola Win, która nie chce akceptować Unicode (tak jak to robi, ponieważ domyślam się, że Win2k jest domyślnie). Jest to domyślne kodowanie systemu. Wypróbuj ten kod i zobacz, co daje:
jeśli mówi ascii, to jest twoja przyczyna ;-) Musisz utworzyć plik o nazwie sitecustomize.py i umieścić go w ścieżce Pythona (umieściłem go w /usr/lib/python2.5/site-packages, ale to jest różnica Win - to jest c: \ python \ lib \ site-packages czy coś), z następującą zawartością:
i być może będziesz chciał określić kodowanie również w swoich plikach:
Edycja: więcej informacji można znaleźć w doskonałej książce Dive into Python
źródło
Coś podobnego do odpowiedzi JF Sebastiana, ale bardziej bezpośrednie.
Jeśli masz ten problem podczas drukowania do konsoli / terminala, wykonaj następujące czynności:
źródło
set PYTHONIOENCODING=UTF-8
może prowadzić do mojibake, jeśli konsola używa innego kodowania, takiego jak cp437.cp65001
ma różne problemy . Aby wydrukować Unicode na konsoli Windows, należy użyć Unicode API (WriteConsoleW()
), jak zasugerowałem w mojej odpowiedzi, gdziePYTHONIOENCODING
jest używany tylko do zamiany znaków, których nie można przedstawić na bieżącej stronie kodowej OEM?
(WriteConsoleW()
działa nawet dla takich znaków).PYTHONIOENCODING
może być używany, jeśli dane wyjściowe są przekierowywane do pliku.Python 3.6 windows7: Istnieje kilka sposobów na uruchomienie Pythona, możesz użyć konsoli Pythona (która ma logo Pythona) lub konsoli Windows (jest na niej napisane cmd.exe).
Nie mogłem wydrukować znaków utf8 w konsoli systemu Windows. Drukowanie znaków utf-8 wyrzuca mi ten błąd:
Po próbie zrozumienia powyższej odpowiedzi bez zrozumienia stwierdziłem, że był to tylko problem z ustawieniem. Kliknij prawym przyciskiem myszy w górnej części okien konsoli cmd, na karcie
font
wybierz konsolę lucida.źródło
James Sulak zapytał,
Inne rozwiązania zalecają próbę modyfikacji środowiska Windows lub zastąpienia
print()
funkcji Pythona . Poniższa odpowiedź zbliża się do spełnienia prośby Sulaka.W Windows 7, Python 3.5 może drukować Unicode bez rzucania
UnicodeEncodeError
:Zamiast:
print(text)
substytut:
print(str(text).encode('utf-8'))
Zamiast rzucać wyjątek, Python wyświetla teraz niedrukowalne znaki Unicode jako kody szesnastkowe \ xNN , np .:
Halmalo n \ xe2 \ x80 \ x99 \ xc3 \ xa9tait plus qu \ xe2 \ x80 \ x99un point noir
Zamiast
Halmalo n'était plus qu'un point noir
To prawda, że to drugie jest preferowane ceteris paribus , ale poza tym to pierwsze jest całkowicie dokładne w przypadku komunikatów diagnostycznych. Ponieważ wyświetla Unicode jako literalne wartości bajtów, może również pomóc w diagnozowaniu problemów z kodowaniem / dekodowaniem.
Uwaga:
str()
powyżej konieczne jest wezwanie, ponieważ w przeciwnym razieencode()
powoduje Python odrzucić znak Unicode jako krotki liczb.źródło