[python] 파이썬의 기본 인코딩 변경하기?


4 Answers

A) sys.getdefaultencoding() 출력을 제어하려면 다음을 수행하십시오.

python -c 'import sys; print(sys.getdefaultencoding())'

ascii

그때

echo "import sys; sys.setdefaultencoding('utf-16-be')" > sitecustomize.py

PYTHONPATH=".:$PYTHONPATH" python -c 'import sys; print(sys.getdefaultencoding())'

utf-16-be

PYTHONPATH sitecustomize.py를 더 올려 놓을 수 있습니다.

또한 reload(sys).setdefaultencoding 의해 reload(sys).setdefaultencoding 을 시도 할 수도 있습니다.

B) stdin.encodingstdout.encoding 을 제어하려면 stdin.encoding 을 설정 PYTHONIOENCODING .

python -c 'import sys; print(sys.stdin.encoding, sys.stdout.encoding)'

ascii ascii

그때

PYTHONIOENCODING="utf-16-be" python -c 'import sys; 
print(sys.stdin.encoding, sys.stdout.encoding)'

utf-16-be utf-16-be

마지막으로 : A) 또는 B) 또는 둘 다 사용할 수 있습니다 !

Question

콘솔에서 응용 프로그램을 실행할 때 많은 "인코딩 할 수 없습니다"및 "디코딩 할 수 없습니다"문제가 발생합니다. 그러나 Eclipse PyDev IDE에서 기본 문자 인코딩은 UTF-8 설정되어 있으므로 UTF-8 입니다.

나는 기본 인코딩을 설정하기 위해 주위를 둘러 sys.setdefaultencoding 파이썬이 시작할 때 sys.setdefaultencoding 함수를 삭제한다고 말하며 사용할 수 없다.

그렇다면 가장 좋은 해결책은 무엇일까요?




python2 (및 python2 만 해당)와 관련하여 이전 답변 중 일부는 다음과 같은 해킹을 사용합니다.

import sys
reload(sys)  # Reload is a hack
sys.setdefaultencoding('UTF8')

그것을 사용하는 것이 바람직하지 않습니다 ( 이것 또는 this 체크하십시오)

필자의 경우 ipython 노트북을 사용하고 있으며 일단 코드를 실행하면 'print '기능이 더 이상 작동하지 않습니다. 나는 거기에 해결책이 될 것이라고 생각하지만, 여전히 나는 해킹을 사용하는 것이 올바른 선택이 아니어야한다고 생각한다.

많은 옵션을 시도한 후에 저에게 도움이 되는 코드는 sitecustomize.py 에서 동일한 코드를 사용하는 것 입니다. 해당 모듈을 평가 한 후 setdefaultencoding 함수가 sys에서 제거됩니다.

그래서 해결책은 파일 /usr/lib/python2.7/sitecustomize.py 에 코드를 추가하는 것입니다 :

import sys
sys.setdefaultencoding('UTF8')

virtualenvwrapper를 사용하면 ~/.virtualenvs/venv-name/lib/python2.7/sitecustomize.py 파일을 편집 할 수 있습니다.

그리고 파이썬 노트북과 conda를 사용하면 ~/anaconda2/lib/python2.7/sitecustomize.py




PyDev 3.4.1부터는 기본 인코딩이 더 이상 변경되지 않습니다. 자세한 내용은 이 티켓 을 참조하십시오.

이전 버전의 경우 해결책은 PyDev가 기본 인코딩으로 UTF-8로 실행되지 않도록하는 것입니다. Eclipse에서 대화 상자 설정을 실행합니다 (올바르게 실행하면 "구성 실행"). 공통 탭에서 기본 인코딩을 선택할 수 있습니다. 이 오류를 '초기'(즉, PyDev 환경에서)로 사용하려면 US-ASCII로 변경하십시오. 이 해결 방법은 원본 블로그 게시물을 참조하십시오.




첫 번째 : reload(sys) 및 출력 터미널 스트림의 필요성과 관련하여 임의의 기본 인코딩을 설정하는 것은 좋지 않습니다. reload 는 sys.stdin / stdout 스트림, sys.excepthook 등과 같이 환경에 따라 sys에있는 것들을 변경합니다.

stdout에서 인코딩 문제 해결

내가 sys.stdout에서 unicode 문자열과 너비-ascii str (예 : 리터럴)을 print 하는 인코딩 문제를 해결하기위한 가장 좋은 해결책은 다음과 같습니다. sys.stdout (파일과 유사한 객체)을 처리하는 것입니다. 가능하고 선택적으로 관대함 :

  • sys.stdout.encodingNone 이유없이 존재하지 않거나 존재하지 않거나 잘못되었거나 stdout 터미널 또는 스트림이 실제로 수행 할 수있는 것보다 "적은"경우 올바른 .encoding 특성을 제공하십시오. 마지막으로 sys.stdout & sys.stderr 을 번역 파일과 같은 객체로 대체합니다.

  • 터미널 / 스트림이 여전히 발생하는 모든 유니 코드 문자를 인코딩 할 수 없을 때, 그리고 그 때문에 print 를 중단하고 싶지 않을 때 변환 파일과 유사한 객체에서 encode-with-replace 동작을 도입 할 수 있습니다.

예를 들면 다음과 같습니다.

#!/usr/bin/env python
# encoding: utf-8
import sys

class SmartStdout:
    def __init__(self, encoding=None, org_stdout=None):
        if org_stdout is None:
            org_stdout = getattr(sys.stdout, 'org_stdout', sys.stdout)
        self.org_stdout = org_stdout
        self.encoding = encoding or \
                        getattr(org_stdout, 'encoding', None) or 'utf-8'
    def write(self, s):
        self.org_stdout.write(s.encode(self.encoding, 'backslashreplace'))
    def __getattr__(self, name):
        return getattr(self.org_stdout, name)

if __name__ == '__main__':
    if sys.stdout.isatty():
        sys.stdout = sys.stderr = SmartStdout()

    us = u'aouäöüфżß²'
    print us
    sys.stdout.flush()

파이썬 2 / 2 + 3 코드에서 일반 ASCII 문자열 리터럴을 사용

I / O 스트림 인코딩 문제로 인한 것이 아니기 때문에 응용 프로그램 소스 코드 결정과 관련하여 생각하는 글로벌 기본 인코딩 (UTF-8에만 해당)을 변경하는 유일한 이유는 다음과 같습니다. 언제나 u'string' 스타일의 유니 코드를 이스케이프 처리합니다. 이것은 ascii 또는 UTF-8 일반 문자열 리터럴을 일관되게 사용하는 Python 2 또는 Python 2 + 3 소스 코드 기반을 돌봄으로써 일관되게 수행 할 수 있습니다 ( anonbadger 의 기사에 나오는 내용에도 불구하고). 잠재적으로 이러한 문자열은 잠재적으로 침묵합니다. 유니 코드 변환 및 모듈 간 이동 또는 잠재적으로 stdout으로 이동합니다. 이를 위해서는 " # encoding: utf-8 "또는 ascii (선언 없음)를 사용하십시오. 여전히 희소 한 chr # 127을 넘는 ascii 기본 인코딩 오류에서 여전히 매우 바보 같은 방식으로 의존하는 라이브러리를 변경하거나 삭제하십시오.

reload(sys) 사용하지 않고 위의 SmartStdout 체계 이외에 애플리케이션 시작시 (및 / 또는 sitecustomize.py를 통해 reload(sys) .

...
def set_defaultencoding_globally(encoding='utf-8'):
    assert sys.getdefaultencoding() in ('ascii', 'mbcs', encoding)
    import imp
    _sys_org = imp.load_dynamic('_sys_org', 'sys')
    _sys_org.setdefaultencoding(encoding)

if __name__ == '__main__':
    sys.stdout = sys.stderr = SmartStdout()
    set_defaultencoding_globally('utf-8') 
    s = 'aouäöüфżß²'
    print s

이런 식으로 문자열 리터럴과 대부분의 연산 (문자 반복 제외)은 유니 코드 변환을 생각하지 않고 Python3 만있는 것처럼 편안하게 작동합니다. 물론 File I / O는 파이썬 3에서와 같이 인코딩에 관해서는 특별한주의가 필요합니다.

참고 : 그런 다음 평야 문자열은 SmartStdout 에서 utf-8에서 유니 코드로 암시 적으로 변환되어 출력 스트림 SmartStdout 으로 변환됩니다.




이는 (1) Python 2.7 및 3을 실행하는 Windows 플랫폼 (2)에서 소프트웨어의 멋진 부분 (즉, 사용자가 직접 작성하지 않았으므로 인코딩 / 디코드 인쇄의 후보가 아니기 때문에 짜증이났습니다. 예를 들어, Stephan Boyer가 First Order Logic Prover의 교육자 피버의 출력에서 ​​사용하는 깔끔한 First Order Logic 기호와 같이 IDLE 환경 ( "Pythonwin"은 괜찮은 유니 코드를 인쇄합니다)에서 "꽤 유니 코드 문자"를 표시하지 않습니다.

나는 sys reload를 강요하는 아이디어를 좋아하지 않았고, PYTHONIOENCODING과 같은 환경 변수를 설정하는 시스템을 만들 수 없었다 (직접 Windows 환경 변수를 시도해 보았고 siteecustomize.py를 site-customize.py로 하나 놓기도했다. 라이너 = 'utf-8').

따라서 성공하기 위해 해킹하고자한다면 IDLE 디렉토리 (일반적으로 "C : \ Python27 \ Lib \ idlelib")로 이동하십시오. IOBinding.py 파일을 찾으십시오. 해당 파일의 복사본을 만들어 다른 위치에 저장하면 선택할 때 원본 동작으로 되돌릴 수 있습니다. 편집기 (예 : IDLE)로 idlelib의 파일을 엽니 다. 이 코드 영역으로 이동 :

# Encoding for file names
filesystemencoding = sys.getfilesystemencoding()

encoding = "ascii"
if sys.platform == 'win32':
    # On Windows, we could use "mbcs". However, to give the user
    # a portable encoding name, we need to find the code page 
    try:
        # --> 6/5/17 hack to force IDLE to display utf-8 rather than cp1252
        # --> encoding = locale.getdefaultlocale()[1]
        encoding = 'utf-8'
        codecs.lookup(encoding)
    except LookupError:
        pass

즉, 인코딩 변수를 locale.getdefaultlocale 과 같게 만드는 ' try '다음의 원래 코드 줄을 주석 처리합니다 (원하지 않는 cp1252를 제공하기 때문에). 대신 'utf-8' '(그림과 같이' encoding = 'utf-8 '줄을 추가).

나는 이것이 stdout에 대한 IDLE 디스플레이에만 영향을 미치고 파일 이름 등에 사용되는 인코딩에는 영향을 미치지 않는다고 생각한다. (이것은 filesystemencoding 이전에 얻어진다). 나중에 IDLE에서 실행되는 다른 코드에 문제가있는 경우 IOBinding.py 파일을 원래의 수정되지 않은 파일로 바꿉니다.




Related