etc./StackOverFlow

Python에서 수동으로 예외 발생(던지기)

청렴결백한 만능 재주꾼 2021. 11. 11. 07:58
반응형

질문자 :TIMEX


except 블록을 통해 catch할 수 있도록 Python에서 예외를 발생시키는 방법은 무엇입니까?



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

이러한 인수는 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

예를 들어, 예외 절 내부에서 특정 유형의 오류가 발생했음을 기록하고 다시 발생시키고 싶을 수 있습니다. 스택 추적을 유지하면서 이를 수행하는 가장 좋은 방법은 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.

모든 최신 버전에서 BaseException 유형을 발생시키지 않기 때문에 TypeError 올바른 예외를 확인하지 않고 문제를 인식하는 검토자가 없으면 프로덕션에 들어갈 수 있습니다.

사용 예

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

Aaron Hall

이러지 마세요 . 맨손으로 Exception 것은 절대적으로 옳은 일이 아닙니다. 대신 Aaron Hall의 훌륭한 답변을 참조하십시오.

이보다 더 파이썬적일 수는 없습니다.

 raise Exception("I know python!")

더 많은 정보를 원하시면 python에 대한 raise 문 문서 를 참조하십시오.


Gabriel Hurley

Python3에는 예외 발생을 위한 4가지 다른 구문이 있습니다.

 1. raise exception 2. raise exception (args) 3. raise 4. raise exception (args) from 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 execption 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

N Randhawa

예상치 못한 상황에 대한 응답으로 예외를 throw해야 하고 catch할 의도가 전혀 없지만 발생하는 경우 디버그할 수 있도록 빠르게 실패하는 일반적인 경우 — 가장 논리적인 경우는 다음과 같습니다. AssertionError :

 if 0 < distance <= RADIUS: #Do something. elif RADIUS < distance: #Do something. else: raise AssertionError("Unexpected value of 'distance'!", distance)

Evgeni Sergeev

기존 답변을 먼저 읽으십시오. 이것은 부록일 뿐입니다.

인수를 사용하거나 사용하지 않고 예외를 발생시킬 수 있습니다.

예시:

 raise SystemExit

프로그램을 종료하지만 무슨 일이 일어났는지 알고 싶을 수도 있습니다. 따라서 이것을 사용할 수 있습니다.

 raise SystemExit("program exited")

이것은 프로그램을 닫기 전에 "프로그램 종료"를 stderr에 인쇄합니다.


Anant Prakash

참고로 일반 예외를 처리하고 싶은 경우가 있습니다. 많은 파일을 처리하고 오류를 기록하는 경우 파일에 대해 발생하는 모든 오류를 잡아 기록하고 나머지 파일을 계속 처리할 수 있습니다. 그 경우,

 try: foo() except Exception as e: print(e) # Print out handled error

차단하는 것이 좋은 방법입니다. 당신은 여전히 할 수 있습니다 raise 당신은 그들이 무엇을 의미하는지 알 수 있도록하지만, 특정 예외.


markemus

예외를 던지는 또 다른 방법은 assert 입니다. assert를 사용하여 조건이 충족되고 있는지 확인할 수 있습니다. 그렇지 않으면 AssertionError 합니다. 자세한 내용은 여기 를 참조하십시오.

 def avg(marks): assert len(marks) != 0,"List is empty." return sum(marks)/len(marks) mark2 = [55,88,78,90,79] print("Average of mark2:",avg(mark2)) mark1 = [] print("Average of mark1:",avg(mark1))

Rehan Haider

그러기 위해서는 python의 raise 문을 배워야 합니다. try 블록 안에 보관해야 합니다. 예시 -

 try: raise TypeError #remove TypeError by any other error if you want except TypeError: print('TypeError raised')

Grasshopper

사용자 정의 예외를 발생 시킬 수도 있습니다. 예를 들어, 라이브러리를 작성하는 경우 모듈에 대한 기본 예외 클래스를 만든 다음 사용자 지정 하위 예외를 더 구체적으로 설정하는 것이 매우 좋습니다.

다음과 같이 달성할 수 있습니다.

 class MyModuleBaseClass(Exception): pass class MoreSpecificException(MyModuleBaseClass): pass # To raise custom exceptions, you can just # use the raise keyword raise MoreSpecificException raise MoreSpecificException('message')

Exception , TypeError , ValueError 등과 같은 일반 예외 클래스에서 사용자 정의 예외 클래스를 상속하면 됩니다.


LuisAFK

모든 예외를 포착하려면 예외 계층의 맨 위에 BaseException

#1 예외를 잡아라

 try: #Do something except BaseException as error: print('An exception occurred: {}'.format(error))

#2 예외 발생

 try: #Do something except BaseException as error: raise 'An exception occurred: {}'.format(error)

위 코드는 Python 2.7부터 최신 버전까지 지원합니다.

참조 : https://docs.python.org/3.9/library/exceptions.html#exception-hierarchy


Sathia

어떤 오류를 발생시킬지 신경 쓰지 않는다면 assert AssertionError 를 발생시킬 수 있습니다:

 >>> assert False, "Manually raised error" Traceback (most recent call last): File "<pyshell#24>", line 1, in <module> assert False, "Manually raised error" AssertionError: Manually raised error >>>

assert 키워드는 조건이 False AssertionError 발생시킵니다. 이 경우 False 직접 지정하여 오류를 발생시키지만 발생하려는 텍스트를 갖도록 하려면 쉼표를 추가하고 원하는 오류 텍스트를 지정합니다. , 이 경우 Manually raised error 작성했으며 해당 텍스트와 함께 오류를 발생시킵니다.


U12-Forward

출처 : http:www.stackoverflow.com/questions/2052390/manually-raising-throwing-an-exception-in-python

반응형