2012-11-06 4 views
6

파이썬 2.7.x에서 유니 코드를 메시지에 포함시키는 예외를 발생 시키려고합니다. 나는 그것을 작동시키는 것처럼 보일 수 없다.파이썬 2에서 비 영어 문자를 포함하는 예외를 발생시킬 수 있습니까?

오류 메시지에 유니 코드를 포함 시키거나 지원하지 않는가? 아니면 sys.stderr을 볼 필요가 있습니까?

# -*- coding: utf-8 -*- 
class MyException(Exception): 
    def __init__(self, value): 
    self.value = value 
    def __str__(self): 
    return self.value 
    def __repr__(self): 
    return self.value 
    def __unicode__(self): 
    return self.value 

desc = u'something bad with field \u4443' 

try: 
    raise MyException(desc) 
except MyException as e: 
    print(u'Inside try block : ' + unicode(e)) 

# here is what i wish to make work 
raise MyException(desc) 

실행중인 스크립트는 아래 출력을 생성합니다. 내 시도/예외 내에서 문제없이 문자열을 인쇄 할 수 있습니다.

내 문제는 try/except 외부입니다.

Inside try block : something bad with field 䑃 
Traceback (most recent call last): 
    File "C:\Python27\lib\bdb.py", line 387, in run 
    exec cmd in globals, locals 
    File "C:\Users\ghis3080\r.py", line 25, in <module> 
    raise MyException(desc) 
MyException: something bad with field \u4443 

미리 감사드립니다.

답변

1

동작은 Python 버전과 환경에 따라 다릅니다. 파이썬 3 일 sys.stderr에 대한 문자 인코딩 오류 처리기는 항상 'backslashreplace'입니다 :

from __future__ import unicode_literals, print_function 
import sys 

s = 'unicode "\u2323" smile' 
print(s) 
print(s, file=sys.stderr) 
try: 
    raise RuntimeError(s) 
except Exception as e: 
    print(e.args[0]) 
    print(e.args[0], file=sys.stderr) 
    raise 

가 python3 :

$ PYTHONIOENCODING=ascii:ignore python3 raise_unicode.py 
unicode "" smile 
unicode "\u2323" smile 
unicode "" smile 
unicode "\u2323" smile 
Traceback (most recent call last): 
    File "raise_unicode.py", line 8, in <module> 
    raise RuntimeError(s) 
RuntimeError: unicode "\u2323" smile 

python2 :

내 시스템에
$ PYTHONIOENCODING=ascii:ignore python2 raise_unicode.py 
unicode "" smile 
unicode "" smile 
unicode "" smile 
unicode "" smile 
Traceback (most recent call last): 
    File "raise_unicode.py", line 8, in <module> 
    raise RuntimeError(s) 
RuntimeError 

오류 메시지가 먹 python2.

참고 : Windows에서 당신은 시도 할 수 :

T:\> set PYTHONIOENCODING=ascii:ignore 
T:\> python raise_unicode.py 

비교를 위해 : 내 경우

$ python3 raise_unicode.py 
unicode "⌣" smile 
unicode "⌣" smile 
unicode "⌣" smile 
unicode "⌣" smile 
Traceback (most recent call last): 
    File "raise_unicode.py", line 8, in <module> 
    raise RuntimeError(s) 
RuntimeError: unicode "⌣" smile 
2

이것은 파이썬이 작동하는 방식입니다. 나는 당신이보고있는 것이 traceback._some_string()에서 파이썬 코어 라이브러리에 있다고 믿습니다. 이 모듈에서 스택 추적이 완료되면 해당 메서드의 코드는 먼저 str()을 사용하여 메시지를 변환하려고 시도하고 예외가 발생하면 unicode()을 사용하여 메시지를 변환 한 다음 encode("ascii", "backslashreplace")을 사용하여 ASCII로 변환합니다. 당신은 유효한 출력을 얻고 있고 모든 것이 올바르게 작동하고 있습니다. 제 생각에 파이썬은 오류 메시지를 pseudo-down으로 변환하여 플랫폼을 실행하는 데 문제없이 문제없이 표시 할 수 있습니다. 그것은 당신의 캐릭터에 대한 유니 코드 코드 포인트 일뿐입니다. try/except 블록에서 발생하지 않습니다.이 변환은 스택 추적을 생성하는 메커니즘 (예 : catch되지 않는 예외 발생시)과 관련이 있기 때문에 발생합니다.

1

를 귀하의 예제가 정상적으로 작동, 좋은 유니 코드를 인쇄.

하지만 때로는 이스케이프/백 슬래시가없는 유니 코드 문자없이 인쇄 된 예외 스택에 많은 문제가 있습니다. 장애물을 극복하고 일반 메시지를 인쇄 할 수 있습니다.

출력 문제 (Python 2.7, 리눅스) :

~/.../sources/C_patch$ python SO.py 
Traceback (most recent call last): 
    File "SO.py", line 25, in <module> 
    raise SyntaxError(desc) 
SyntaxError 

실제로 변경되지 않은 유니 코드를 확인하려면, 당신은 원시 바이트로 인코딩하고 예외 객체에 공급할 수 :

# -*- coding: utf-8 -*- 
desc = u'something bad with field ¾' 
raise SyntaxError(desc.encode('utf-8', 'replace')) 

그것은 단지 잘 리거나 나사 메시지를 인쇄합니다

~/.../sources/C_patch$ python SO.py 
Traceback (most recent call last): 
    File "SO.py", line 3, in <module> 
    raise SyntaxError(desc.encode('utf-8', 'replace')) 
SyntaxError: something bad with field ¾ 
:
# -*- coding: utf-8 -*- 
desc = u'something bad with field ¾' 
raise SyntaxError(desc.encode('utf-8', 'replace')) 

이 시간 당신은 전체 메시지가 표시됩니다 0

원하는 경우 생성자에서 value.encode('utf-8', 'replace')을 수행 할 수 있지만 시스템 예외가있는 경우 예제 에서처럼 raise 문에서 수행해야합니다.

힌트는 여기에서 가져온 것입니다 : Overcoming frustration: Correctly using unicode in python2 (도우미가 많은 대형 라이브러리가 있으며, 위의 예에서 모두 제거 할 수 있습니다).

+0

.encode ('utf-8') 정말 도움이되었지만 두 번째 매개 변수를 사용할 필요조차 없었습니다. –

관련 문제