질문 : Python에서 수동으로 예외 발생 (던지기)
except
블록을 통해 잡을 수 있도록 파이썬에서 예외를 어떻게 발생시킬 수 있습니까?
답변
Python에서 예외를 수동으로 생성/제기하는 방법은 무엇입니까?
의미 상 문제에 맞는 가장 구체적인 예외 생성자를 사용합니다 .
메시지를 구체적으로 작성하십시오. 예 :
raise ValueError('A very specific bad thing happened.')
일반 예외를 제기하지 않음
Exception
발생시키지 마십시오. 이를 포착하려면 하위 클래스를 구성하는 다른 모든 특정 예외를 포착해야합니다.0
문제 1: 버그 숨기기
raise Exception('I know Python!') # Don't! If you catch, likely to hide bugs.
예를 들면 :
def demo_bad_catch():
try:
raise ValueError('Represents a hidden bug, do not catch this')
raise Exception('This is the exception you expect to handle')
except Exception as error:
print('Caught this error: ' + repr(error))
>>> demo_bad_catch()
Caught this error: ValueError('Represents a hidden bug, do not catch this',)
문제 2: 잡히지 않음
그리고 더 구체적인 catch는 일반적인 예외를 포착하지 않습니다.
def demo_no_catch():
try:
raise Exception('general exceptions not caught by specific handling')
except ValueError as e:
print('we will not catch exception: Exception')
>>> demo_no_catch()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in demo_no_catch
Exception: general exceptions not caught by specific handling
모범 사례: "raise" 설명
대신, 의미 상 문제에 맞는 가장 구체적인 Exception 생성자를 사용하십시오 .
raise ValueError('A very specific bad thing happened')
또한 임의의 수의 인수를 생성자에 전달할 수 있습니다.
raise ValueError('A very specific bad thing happened', 'foo', 'bar', 'baz')
이러한 인수는 Exception
개체 args
속성에 의해 액세스됩니다. 예를 들면 :
try:
some_code_that_may_raise_our_value_error()
except ValueError as err:
print(err.args)
출력
('message', 'foo', 'bar', 'baz')
Python 2.5에서는 사용자가 Exceptions 하위 클래스를 만들고 args
사용을 중지하도록 유도하기 위해 message
BaseException
에 추가되었지만 message
도입 및 args의 원래 사용 중단이 철회되었습니다 .
모범 사례: "except" 절
예를 들어 except 절 안에있을 때 특정 유형의 오류가 발생했음을 기록한 다음 다시 발생시킬 수 있습니다. 스택 추적을 유지하면서이를 수행하는 가장 좋은 방법은 bare raise 문을 사용하는 것입니다. 예를 들면 :
logger = logging.getLogger(__name__)
try:
do_something_in_app_that_breaks_easily()
except AppError as error:
logger.error(error)
raise # just this!
# raise AppError # Don't do this, you'll lose the stack trace!
오류를 수정하지 마십시오... 하지만 굳이 원하신다면.
sys.exc_info()
)를 사용하여 스택 추적 (및 오류 값)을 보존 할 수 있지만, 이것은 오류가 발생하기 쉽고 Python 2와 3간에 호환성 문제가 raise
를 사용하여 다시 레이즈하는 것을 선호합니다.
설명하기 위해 sys.exc_info()
는 유형, 값 및 역 추적을 반환합니다.
type, value, traceback = sys.exc_info()
이것은 Python 2의 구문입니다. Python 3과 호환되지 않습니다.
raise AppError, error, sys.exc_info()[2] # avoid this.
# Equivalently, as error *is* the second object:
raise sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]
원하는 경우 새 레이즈에서 발생하는 작업을 수정할 수 있습니다. 예를 들어 인스턴스에 대한 args
def error():
raise ValueError('oops!')
def catch_error_modify_message():
try:
error()
except ValueError:
error_type, error_instance, traceback = sys.exc_info()
error_instance.args = (error_instance.args[0] + ' <modification>',)
raise error_type, error_instance, traceback
그리고 우리는 args를 수정하는 동안 전체 트레이스 백을 보존했습니다. 이것은 모범 사례 가 아니며 Python 3에서 잘못된 구문 입니다 (호환성을 유지하기가 훨씬 더 어려워 짐).
>>> catch_error_modify_message()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in catch_error_modify_message
File "<stdin>", line 2, in error
ValueError: oops! <modification>
raise error.with_traceback(sys.exc_info()[2])
다시 말하지만 수동으로 트레이스 백을 조작하지 마십시오. 효율성 이 떨어지고 오류가 발생하기 쉽습니다. 그리고 스레딩과 sys.exc_info
를 사용하는 경우 잘못된 역 추적을 얻을 수도 있습니다 (특히 제어 흐름에 예외 처리를 사용하는 경우-개인적으로 피하는 경향이 있음).
Python 3, 예외 체인
Python 3에서는 트레이스 백을 보존하는 예외를 연결할 수 있습니다.
raise RuntimeError('specific message') from error
주의 :
- 이 오류 유형 제기 변경 허용하고 않는
- 이것은 Python 2와 호환 되지 않습니다.
사용되지 않는 방법:
이들은 쉽게 숨기고 프로덕션 코드에 들어갈 수도 있습니다. 예외를 발생시키고 싶고, 그렇게하면 예외가 발생 하지만 의도 한 것은 아닙니다!
다음은 Python 2에서 유효하지만 Python 3에서는 유효하지 않습니다 .
raise ValueError, 'message' # Don't do this, it's deprecated!
훨씬 이전 버전의 Python (2.4 이하)에서만 유효하지만 여전히 문자열을 올리는 사람들을 볼 수 있습니다.
raise 'message' # really really wrong. don't do this.
모든 최신 버전에서는 BaseException
유형을 발생시키지 않기 때문에 TypeError
올바른 예외를 확인하지 않고 문제를 알고있는 검토자가 없으면 프로덕션에 들어갈 수 있습니다.
사용 예
내 API를 잘못 사용하는 경우 내 API에 대해 소비자에게 경고하기 위해 예외를 발생시킵니다.
def api_func(foo):
'''foo should be either 'baz' or 'bar'. returns something very useful.'''
if foo not in _ALLOWED_ARGS:
raise ValueError('{foo} wrong, use "baz" or "bar"'.format(foo=repr(foo)))
제안 시 사용자 고유의 오류 유형 생성
"고의로 오류를 만들어서 예외로 들어가고 싶다"
고유 한 오류 유형을 생성 할 수 있습니다. 애플리케이션에 특정 문제가 있음을 나타내려면 예외 계층 구조에서 적절한 지점을 하위 클래스로 지정하면됩니다.
class MyAppLookupError(LookupError):
'''raise this when there's a lookup error for my app'''
및 사용법 :
if important_key not in resource_dict and not ok_to_be_missing:
raise MyAppLookupError('resource is missing, and that is not ok.')
출처 : https://stackoverflow.com/questions/2052390/manually-raising-throwing-an-exception-in-python
'프로그래밍 언어 > Python' 카테고리의 다른 글
파이썬 스레드에서 반환 값을 얻는 방법 (0) | 2021.08.13 |
---|---|
Python을 사용하여 시스템 호스트 이름을 얻는 방법 (0) | 2021.08.13 |
pip로 특정 패키지 버전 설치 (0) | 2021.08.12 |
Python 클래스에서 동등성 ( "equality")을 지원하는 방법 (0) | 2021.08.11 |
Python unittest-assert Raises의 반대? (0) | 2021.08.11 |