Python에서 커스텀 메시지와 동일한 예외를 발생시키는 방법은 무엇입니까?
나는 이것을 가지고 있다.try
내 코드 차단:
try:
do_something_that_might_raise_an_exception()
except ValueError as err:
errmsg = 'My custom error message.'
raise ValueError(errmsg)
엄밀히 말하면, 나는 사실 한 마리 더 키우고 있다. ValueError
,가 아니라ValueError
에 의해 던져진do_something...()
라고 불립니다.err
이 경우는,커스텀 메시지를 첨부하려면err
? 다음 코드를 시도했지만 다음 코드 때문에 실패합니다.err
,aValueError
인스턴스, 호출할 수 없음:
try:
do_something_that_might_raise_an_exception()
except ValueError as err:
errmsg = 'My custom error message.'
raise err(errmsg)
운이 좋아서 python 3.x만 지원한다면 정말 멋진 일이 될 것입니다.
에서 기르다.
raise from을 사용하여 예외를 묶을 수 있습니다.
try:
1 / 0
except ZeroDivisionError as e:
raise Exception('Smelly socks') from e
이 경우, 발신자가 검출하는 예외에는, 델이 예외를 제기한 장소의 회선 번호가 포함됩니다.
Traceback (most recent call last):
File "test.py", line 2, in <module>
1 / 0
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "test.py", line 4, in <module>
raise Exception('Smelly socks') from e
Exception: Smelly socks
아래쪽 예외에는 예외를 제기한 스택 트레이스만 있습니다.발신자는 에 접속하여 원래의 예외를 취득할 수 있습니다.__cause__
예외 속성을 지정합니다.
with_syslogback
또는 with_traceback을 사용할 수 있습니다.
try:
1 / 0
except ZeroDivisionError as e:
raise Exception('Smelly socks').with_traceback(e.__traceback__)
이 폼을 사용하면 발신자가 검출하는 예외는 원래 에러가 발생한 장소로부터의 트레이스백이 됩니다.
Traceback (most recent call last):
File "test.py", line 2, in <module>
1 / 0
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test.py", line 4, in <module>
raise Exception('Smelly socks').with_traceback(e.__traceback__)
File "test.py", line 2, in <module>
1 / 0
Exception: Smelly socks
아래쪽 예외에는 비활성 분할을 수행한 행과 예외를 다시 발생시킨 행이 있습니다.
업데이트: Python 3의 경우 Ben의 답변을 확인하십시오.
현재 예외에 메시지를 첨부하고 다시 작성하려면: (외부 시행/예외는 효과를 나타내기 위한 것입니다.)
python 2.x의 경우 x>=6:
try:
try:
raise ValueError # something bad...
except ValueError as err:
err.message=err.message+" hello"
raise # re-raise current exception
except ValueError as e:
print(" got error of type "+ str(type(e))+" with message " +e.message)
또, 이 방법은, 만약 이 데이터로부터 파생된 것이라면, 올바른 일을 할 것입니다.ValueError
.예를들면UnicodeDecodeError
.
원하는 대로 추가할 수 있습니다.err
.예를들면err.problematic_array=[1,2,3]
.
편집: 코멘트의 @Ducan 포인트는 위의 python 3에서는 동작하지 않습니다..message
의 멤버가 아니다.ValueError
대신 다음을 사용할 수 있습니다(유효한 python 2.6 이후 또는 3.x).
try:
try:
raise ValueError
except ValueError as err:
if not err.args:
err.args=('',)
err.args = err.args + ("hello",)
raise
except ValueError as e:
print(" error was "+ str(type(e))+str(e.args))
편집 2:
목적에 따라 자신의 변수 이름으로 추가 정보를 추가할 수도 있습니다.python2와 python3의 경우:
try:
try:
raise ValueError
except ValueError as err:
err.extra_info = "hello"
raise
except ValueError as e:
print(" error was "+ str(type(e))+str(e))
if 'extra_info' in dir(e):
print e.extra_info
모든 답변이 e.args[0]에 정보를 추가하여 기존 오류 메시지를 변경하는 것 같습니다.대신 args 태플을 확장하면 단점이 있나요?가능한 장점은 해당 문자열을 해석할 필요가 있는 경우에는 원래 오류 메시지를 그대로 둘 수 있다는 것입니다.또한 커스텀 오류 처리로 여러 개의 메시지 또는 오류 코드가 생성된 경우(시스템 모니터링 도구를 통해) 여러 요소를 태플에 추가할 수 있습니다.
## Approach #1, if the exception may not be derived from Exception and well-behaved:
def to_int(x):
try:
return int(x)
except Exception as e:
e.args = (e.args if e.args else tuple()) + ('Custom message',)
raise
>>> to_int('12')
12
>>> to_int('12 monkeys')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in to_int
ValueError: ("invalid literal for int() with base 10: '12 monkeys'", 'Custom message')
또는
## Approach #2, if the exception is always derived from Exception and well-behaved:
def to_int(x):
try:
return int(x)
except Exception as e:
e.args += ('Custom message',)
raise
>>> to_int('12')
12
>>> to_int('12 monkeys')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in to_int
ValueError: ("invalid literal for int() with base 10: '12 monkeys'", 'Custom message')
이 접근법의 단점을 알 수 있습니까?
try:
try:
int('a')
except ValueError as e:
raise ValueError('There is a problem: {0}'.format(e))
except ValueError as err:
print err
인쇄:
There is a problem: invalid literal for int() with base 10: 'a'
이것은 Python 3에서만 동작합니다.예외의 원래 인수를 수정하고 고유한 인수를 추가할 수 있습니다.
예외는 작성된 Arg를 기억합니다.이것은 당신이 예외를 수정할 수 있도록 하기 위한 것이라고 생각합니다.
'''에서reraise
예외의 원래 인수 앞에 원하는 새로운 인수(메시지 등)를 추가합니다.마지막으로 트레이스백 이력을 유지하면서 예외를 다시 발생시킵니다.
def reraise(e, *args):
'''re-raise an exception with extra arguments
:param e: The exception to reraise
:param args: Extra args to add to the exception
'''
# e.args is a tuple of arguments that the exception with instantiated with.
#
e.args = args + e.args
# Recreate the expection and preserve the traceback info so thta we can see
# where this exception originated.
#
raise e.with_traceback(e.__traceback__)
def bad():
raise ValueError('bad')
def very():
try:
bad()
except Exception as e:
reraise(e, 'very')
def very_very():
try:
very()
except Exception as e:
reraise(e, 'very')
very_very()
산출량
Traceback (most recent call last):
File "main.py", line 35, in <module>
very_very()
File "main.py", line 30, in very_very
reraise(e, 'very')
File "main.py", line 15, in reraise
raise e.with_traceback(e.__traceback__)
File "main.py", line 28, in very_very
very()
File "main.py", line 24, in very
reraise(e, 'very')
File "main.py", line 15, in reraise
raise e.with_traceback(e.__traceback__)
File "main.py", line 22, in very
bad()
File "main.py", line 18, in bad
raise ValueError('bad')
ValueError: ('very', 'very', 'bad')
이 코드 템플릿을 사용하면 커스텀메시지로 예외를 발생시킬 수 있습니다.
try:
raise ValueError
except ValueError as err:
raise type(err)("my message")
다음 중 하나를 사용하여 오류 메시지와 함께 새 예외를 발생시킵니다.
raise Exception('your error message')
또는
raise ValueError('your error message')
'from'을 사용하여 오류 메시지를 현재 예외에 첨부(바꾸기)하려는 위치 내에서 다음을 수행합니다(Python 3.x만 지원됨).
except ValueError as e:
raise ValueError('your message') from e
이것은 원래 트레이스백을 유지하면서 Python 2.7과 3.x에서 예외 메시지를 수정하기 위해 사용하는 기능입니다.그것은 필요하다
def reraise_modify(caught_exc, append_msg, prepend=False):
"""Append message to exception while preserving attributes.
Preserves exception class, and exception traceback.
Note:
This function needs to be called inside an except because
`sys.exc_info()` requires the exception context.
Args:
caught_exc(Exception): The caught exception object
append_msg(str): The message to append to the caught exception
prepend(bool): If True prepend the message to args instead of appending
Returns:
None
Side Effects:
Re-raises the exception with the preserved data / trace but
modified message
"""
ExceptClass = type(caught_exc)
# Keep old traceback
traceback = sys.exc_info()[2]
if not caught_exc.args:
# If no args, create our own tuple
arg_list = [append_msg]
else:
# Take the last arg
# If it is a string
# append your message.
# Otherwise append it to the
# arg list(Not as pretty)
arg_list = list(caught_exc.args[:-1])
last_arg = caught_exc.args[-1]
if isinstance(last_arg, str):
if prepend:
arg_list.append(append_msg + last_arg)
else:
arg_list.append(last_arg + append_msg)
else:
arg_list += [last_arg, append_msg]
caught_exc.args = tuple(arg_list)
six.reraise(ExceptClass,
caught_exc,
traceback)
현재 답변이 잘 작동하지 않습니다. 예외를 다시 포착하지 않으면 첨부된 메시지가 표시되지 않습니다.
그러나 다음과 같이 하면 예외 재캐치 여부에 관계없이 모두 트레이스가 유지되고 추가된 메시지가 표시됩니다.
try:
raise ValueError("Original message")
except ValueError as err:
t, v, tb = sys.exc_info()
raise t, ValueError(err.message + " Appended Info"), tb
(Python 2.7을 사용했지만 Python 3에서는 사용해 본 적이 없습니다.)
에는 Python 3의 삽입 예외가 .strerror
추가:
except ValueError as err:
err.strerror = "New error message"
raise err
위의 어느 솔루션도 원하는 대로 되지 않았습니다.즉, 에러 메시지의 첫 부분에 정보를 추가하는 것입니다.사용자 지정 메시지를 먼저 볼 수 있도록 했습니다.
이 방법은 효과가 있었습니다.
exception_raised = False
try:
do_something_that_might_raise_an_exception()
except ValueError as e:
message = str(e)
exception_raised = True
if exception_raised:
message_to_prepend = "Custom text"
raise ValueError(message_to_prepend + message)
아래 시도:
try:
raise ValueError("Original message. ")
except Exception as err:
message = 'My custom error message. '
# Change the order below to "(message + str(err),)" if custom message is needed first.
err.args = (str(err) + message,)
raise
출력:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
1 try:
----> 2 raise ValueError("Original message")
3 except Exception as err:
4 message = 'My custom error message.'
5 err.args = (str(err) + ". " + message,)
ValueError: Original message. My custom error message.
이 컴팩트한 버전의 @RobinL을 사용해 보고, 작업도 했습니다.
try:
do_something_that_might_raise_an_exception()
except ValueError as e:
raise ValueError(f'Custom text {e}')
제안된 솔루션 중 많은 부분이 예외를 다시 제기하는 것으로, 이는 잘못된 관행으로 간주됩니다.이렇게 간단한 걸로 충분할 거야
try:
import settings
except ModuleNotFoundError:
print("Something meaningfull\n")
raise
따라서 오류 메시지를 먼저 인쇄한 후 스택 트레이스를 올리거나 sys.exit(1)을 사용하여 종료하고 오류 메시지를 전혀 표시하지 않습니다.
에러 타입을 커스터마이즈 하는 경우는, ValueError 에 근거해 에러 클래스를 정의할 수 있습니다.
언급URL : https://stackoverflow.com/questions/9157210/how-do-i-raise-the-same-exception-with-a-custom-message-in-python
'source' 카테고리의 다른 글
len() 함수의 비용 (0) | 2022.10.20 |
---|---|
'LIKE(%this%)' 또는 '%this%' 및 'something=something'이 작동하지 않습니다. (0) | 2022.10.20 |
Java 속성 파일에 여러 줄의 코멘트를 추가할 수 있습니까? (0) | 2022.10.19 |
단일 인스턴스 Java 애플리케이션을 구현하려면 어떻게 해야 합니까? (0) | 2022.10.19 |
Node.js 글로벌 변수 (0) | 2022.10.19 |