except
나중에 블록 을 통해 catch할 수 있도록 Python에서 예외를 발생시키는 방법은 무엇입니까?
[python] Python에서 수동으로 예외 발생(throw)
Python에서 수동으로 예외를 던지거나 발생시키는 방법은 무엇입니까?
의미 론적으로 문제에 맞는 가장 구체적인 예외 생성자를 사용하십시오 .
메시지를 구체적으로 작성하십시오. 예:
raise ValueError('A very specific bad thing happened.')
일반 예외를 발생시키지 마십시오
제네릭을 올리지 마십시오 Exception
. 그것을 잡으려면 그것을 하위 분류하는 다른 모든 더 구체적인 예외를 잡아야 합니다.
문제 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는 일반적인 예외를 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
문
대신 의미상 문제에 맞는 가장 구체적인 예외 생성자를 사용하세요 .
raise ValueError('A very specific bad thing happened')
또한 임의의 수의 인수를 생성자에 전달할 수 있습니다.
raise ValueError('A very specific bad thing happened', 'foo', 'bar', 'baz')
이러한 인수는 개체 의 args
속성에 의해 액세스됩니다. Exception
예를 들어:
try:
some_code_that_may_raise_our_value_error()
except ValueError as err:
print(err.args)
인쇄물
('message', 'foo', 'bar', 'baz')
Python 2.5에서는 사용자가 Exceptions를 하위 클래스로 만들고 사용을 중지하도록 권장 하기 위해 실제 message
속성이 에 추가 되었지만 args 의 도입 및 원래 사용 중단이 철회되었습니다 .BaseException
args
message
모범 사례: 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>
파이썬 3 에서 :
raise error.with_traceback(sys.exc_info()[2])
다시 말하지만 트레이스백을 수동으로 조작하지 마십시오. 덜 효율적 이고 오류가 발생하기 쉽습니다 . 그리고 스레딩을 사용하고 sys.exc_info
있고 잘못된 역추적을 얻을 수도 있습니다(특히 제어 흐름에 예외 처리를 사용하는 경우 개인적으로 피하는 경향이 있음).
파이썬 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.
TypeError
모든 최신 버전에서는 유형 을 발생시키지 않기 때문에 실제로 발생 BaseException
합니다. 올바른 예외를 확인하지 않고 문제를 인식하는 검토자가 없으면 프로덕션에 들어갈 수 있습니다.
사용 예
내 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.')
이러지 마세요 . 맨손으로 키우는
Exception
것은 절대옳지 않습니다 . 대신 Aaron Hall의 훌륭한 답변 을 참조하십시오.
이보다 더 Pythonic할 수는 없습니다.
raise Exception("I know Python!")
Exception
던지려는 특정 유형의 예외로 교체하십시오 .
자세한 내용 은 Python용 raise 문 설명서 를 참조하십시오.
Python 3에는 예외를 발생시키는 네 가지 구문이 있습니다.
- 예외를 일으키다
- 예외 발생(인수)
- 들어올리다
- original_exception에서 예외(인수) 발생
1. 예외 발생 대 2. 예외 발생(인수)
raise exception (args)
예외를 발생시키는 데 사용하는 경우 args
아래 예와 같이 예외 개체를 인쇄할 때 인쇄됩니다.
# Raise exception (args)
try:
raise ValueError("I have raised an Exception")
except ValueError as exp:
print ("Error", exp) # Output -> Error I have raised an Exception
# Raise exception
try:
raise ValueError
except ValueError as exp:
print ("Error", exp) # Output -> Error
3. 성명서 인상
raise
인수가 없는 문은 마지막 예외를 다시 발생시킵니다 .
예외를 포착한 후 일부 작업을 수행한 다음 다시 발생시키려는 경우에 유용합니다. 그러나 이전에 예외가 없었다면 raise
명령문은 TypeError
예외를 발생시킵니다.
def somefunction():
print("some cleaning")
a=10
b=0
result=None
try:
result=a/b
print(result)
except Exception: # Output ->
somefunction() # Some cleaning
raise # Traceback (most recent call last):
# File "python", line 8, in <module>
# ZeroDivisionError: division by zero
4. original_exception에서 예외(인수) 발생
이 문은 아래 예와 같이 다른 예외에 대한 응답으로 발생한 예외가 원래 예외의 세부 정보를 포함할 수 있는 예외 연결을 만드는 데 사용됩니다.
class MyCustomException(Exception):
pass
a=10
b=0
reuslt=None
try:
try:
result=a/b
except ZeroDivisionError as exp:
print("ZeroDivisionError -- ",exp)
raise MyCustomException("Zero Division ") from exp
except MyCustomException as exp:
print("MyException",exp)
print(exp.__cause__)
산출:
ZeroDivisionError -- division by zero
MyException Zero Division
division by zero