[python] Python, 유니 코드 및 Windows 콘솔

Windows 콘솔에서 유니 코드 문자열을 인쇄하려고하면 UnicodeEncodeError: 'charmap' codec can't encode character ....오류가 발생합니다. Windows 콘솔은 유니 코드 전용 문자를 허용하지 않기 때문이라고 생각합니다. 이 문제를 해결하는 가장 좋은 방법은 무엇입니까? ?이 상황에서 Python이 자동으로 인쇄하는 대신 실패 하게 만드는 방법 이 있습니까?

편집 : Python 2.5를 사용하고 있습니다.


참고 : 체크 표시가있는 @ LasseV.Karlsen 답변은 오래된 것입니다 (2008 년부터). 아래의 솔루션 / 응답 / 제안을주의해서 사용하십시오 !!

@JFSebastian의 답변 은 오늘 (2016 년 1 월 6 일)보다 관련성이 높습니다 .



답변

참고 : 이 답변은 구식입니다 (2008 년부터). 아래 솔루션을주의해서 사용하십시오 !!


다음은 문제와 해결책을 자세히 설명하는 페이지입니다 ( rap.sys.stdout 텍스트를 인스턴스로 랩핑 하는 페이지 검색 ).

PrintFails-파이썬 위키

해당 페이지에서 발췌 한 코드는 다음과 같습니다.

$ python -c 'import sys, codecs, locale; print sys.stdout.encoding; \
    sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); \
    line = u"\u0411\n"; print type(line), len(line); \
    sys.stdout.write(line); print line'
  UTF-8
  <type 'unicode'> 2
  Б
  Б

  $ python -c 'import sys, codecs, locale; print sys.stdout.encoding; \
    sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); \
    line = u"\u0411\n"; print type(line), len(line); \
    sys.stdout.write(line); print line' | cat
  None
  <type 'unicode'> 2
  Б
  Б

그 페이지에 더 많은 정보가 있으며 읽을 가치가 있습니다.


답변

업데이트 : 파이썬 3.6 구현의 PEP 528 : UTF-8로 변경 Windows 콘솔 인코딩 : Windows에서 기본 콘솔은 이제 모든 유니 코드 문자를 사용할 수 있습니다. 내부적으로는 같은 유니 코드 API 사용 아래에 언급 된 패키지를 . 지금 작동해야합니다.win-unicode-consoleprint(unicode_string)


내가 얻을 UnicodeEncodeError: 'charmap' codec can't encode character... 오류입니다.

이 오류는 인쇄하려는 유니 코드 문자를 현재 ( chcp) 콘솔 문자 인코딩 으로 표현할 수 없음을 의미합니다 . 코드 페이지는 종종 cp437~ 1M 유니 코드 문자에서 ~ 0x100 문자 만 나타낼 수있는 8 비트 인코딩입니다 .

>>> u "\ N {EURO SIGN}". encode ( 'cp437')
역 추적 (가장 최근 통화) :
...
UnicodeEncodeError : 'charmap'코덱은 위치 0에서 '\ u20ac'문자를 인코딩 할 수 없습니다.
캐릭터는 

Windows 콘솔은 유니 코드 전용 문자를 허용하지 않기 때문이라고 생각합니다. 이 문제를 해결하는 가장 좋은 방법은 무엇입니까?

Windows 콘솔은 유니 코드 문자를 허용 하며 해당 글꼴이 구성된 경우 해당 문자를 표시 할 수도 있습니다 (BMP 만 해당) . @Daira Hopwood의 답변WriteConsoleW() 에서 제안한대로 API를 사용해야합니다 . 패키지를 투명하게 호출 할 수 있습니다. 즉, package 를 사용하면 스크립트를 수정하지 않아도됩니다 .win-unicode-console

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

Python 3.4, 유니 코드, 다른 언어 및 Windows와의 관계는 무엇입니까?를 참조하십시오 .

?이 상황에서 Python이 자동으로 인쇄하는 대신 실패 하게 만드는 방법 이 있습니까?

?귀하의 경우에 모든 불가피한 문자를 대체하는 것으로 충분하다면 envvar을 설정할 수 PYTHONIOENCODING있습니다 :

T:\> set PYTHONIOENCODING=:replace
T:\> python3 -c "print(u'[\N{EURO SIGN}]')"
[?]

Python 3.6 이상에서 envvar이 비어 있지 않은 문자열로 설정되어 PYTHONIOENCODING있지 않으면 대화식 콘솔 버퍼에 대해 envvar로 지정된 인코딩 이 무시됩니다 PYTHONLEGACYWINDOWSIOENCODING.


답변

코드 페이지를 65001로 변경하도록 제안하는 다른 그럴듯한 답변에도 불구하고 작동하지 않습니다 . (또한, 사용 인코딩 기본값을 변경하는 sys.setdefaultencoding것입니다 좋은 아이디어 없습니다 .)

작동하는 세부 사항 및 코드는 이 질문 을 참조하십시오 .


답변

나쁜 캐릭터를 안정적으로 표현하는 데 관심이 없다면 다음과 같은 것을 사용할 수 있습니다 (python> = 2.6, 3.x 포함).

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

safeprint(u"\N{EM DASH}")

문자열의 잘못된 문자는 Windows 콘솔에서 인쇄 할 수있는 표현으로 변환됩니다.


답변

아래 코드는 Windows에서도 Python 출력을 UTF-8로 콘솔에 출력합니다.

콘솔은 Windows 7에서 문자를 잘 표시하지만 Windows XP에서는 문자를 잘 표시하지 않지만 적어도 작동하고 모든 플랫폼에서 스크립트의 일관된 출력을 얻는 것이 가장 중요합니다. 출력을 파일로 리디렉션 할 수 있습니다.

아래 코드는 Windows에서 Python 2.6으로 테스트되었습니다.


#!/usr/bin/python
# -*- coding: UTF-8 -*-

import codecs, sys

reload(sys)
sys.setdefaultencoding('utf-8')

print sys.getdefaultencoding()

if sys.platform == 'win32':
    try:
        import win32console
    except:
        print "Python Win32 Extensions module is required.\n You can download it from https://sourceforge.net/projects/pywin32/ (x86 and x64 builds are available)\n"
        exit(-1)
    # win32console implementation  of SetConsoleCP does not return a value
    # CP_UTF8 = 65001
    win32console.SetConsoleCP(65001)
    if (win32console.GetConsoleCP() != 65001):
        raise Exception ("Cannot set console codepage to 65001 (UTF-8)")
    win32console.SetConsoleOutputCP(65001)
    if (win32console.GetConsoleOutputCP() != 65001):
        raise Exception ("Cannot set console output codepage to 65001 (UTF-8)")

#import sys, codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
sys.stderr = codecs.getwriter('utf8')(sys.stderr)

print "This is an Е乂αmp١ȅ testing Unicode support using Arabic, Latin, Cyrillic, Greek, Hebrew and CJK code points.\n"


답변

파이썬 스크립트를 실행하기 전에 명령 행에이 코드를 입력하십시오.

chcp 65001 & set PYTHONIOENCODING=utf-8


답변

지암 파올로로 돌라 (Giampaolo Rodolà)의 답변과 같이 더 더러운 : 나는 실제로 인코딩의 전체 주제를 이해하고 Windoze 콘솔에 적용하는 방법을 이해하는 데 오랜 시간 (곧)을 보내고 싶습니다.

현재 나는 단지 프로그램이 충돌하지 않을 것이라는 의미의 sthg를 원했다. 그리고 나는 너무 많은 이국적인 모듈을 가져 오는 것을 포함하지 않았다. 특히 Jython을 사용하고있다. 모듈은 실제로 사용할 수없는 것으로 판명되었습니다).

def pr(s):
    try:
        print(s)
    except UnicodeEncodeError:
        for c in s:
            try:
                print( c, end='')
            except UnicodeEncodeError:
                print( '?', end='')

NB “pr”은 “print”보다 타이프하기가 짧습니다 ( “safeprint”보다 타이핑하기에는 약간 짧습니다) …!