"현대 파이썬에서 커스텀 예외를 선언하는 올바른 방법은?"
예외가 실제로 더 구체적인 예외 유형이 아닌 한 이것은 좋습니다.
class MyException(Exception):
pass
또는 pass
docstring 을 주는 대신 더 좋을 수도 있습니다 (완벽 할 수도 있습니다) .
class MyException(Exception):
"""Raise for my specific kind of exception"""
서브 클래 싱 예외 서브 클래스
로부터 문서
Exception
시스템에 존재하지 않는 모든 내장 예외는이 클래스에서 파생됩니다. 모든 사용자 정의 예외도이 클래스에서 파생되어야합니다.
것을 의미 하는 경우 귀하의 예외는보다 구체적인 예외의 종류, 대신 일반의 예외 있다는 서브 클래스입니다 Exception
(당신은 여전히에서 파생 있고 결과가 될 것입니다 Exception
워드 프로세서 권장으로는). 또한 최소한 docstring을 제공 할 수 있습니다 ( pass
키워드 를 사용하지 않아야 함 ).
class MyAppValueError(ValueError):
'''Raise when my specific value is wrong'''
자신이 만든 속성을 custom으로 설정하십시오 __init__
. dict을 위치 인수로 전달하지 마십시오. 코드의 미래 사용자는 감사 할 것입니다. 더 이상 사용되지 않는 메시지 속성을 사용하는 경우 직접 할당하면 다음을 피할 수 있습니다 DeprecationWarning
.
class MyAppValueError(ValueError):
'''Raise when a specific subset of values in context of app is wrong'''
def __init__(self, message, foo, *args):
self.message = message # without this you may get DeprecationWarning
# Special attribute you desire with your Error,
# perhaps the value that caused the error?:
self.foo = foo
# allow users initialize misc. arguments as any other builtin Error
super(MyAppValueError, self).__init__(message, foo, *args)
자신을 쓸 필요 정말 없습니다 __str__
또는 __repr__
. 내장 된 것들이 매우 좋으며, 당신의 협동 상속 은 그것을 사용하도록 보장합니다.
최고의 답변 비판
어쩌면 나는 질문을 놓쳤지만 왜 그렇지 않습니까?
class MyException(Exception):
pass
다시 말하지만, 위의 문제는 그것을 잡으려면 구체적으로 이름을 지정하거나 (다른 곳에서 만든 경우 가져 오기) 예외를 잡아야한다는 것입니다 (그러나 아마도 모든 유형의 예외를 처리 할 준비가되어 있지는 않습니다. 처리 할 수있는 예외 만 잡아야합니다.) 아래의 유사 비판하지만, 추가의하지 않는 방법을 통해 초기화하는 것을 super
, 당신은 얻을 것이다 DeprecationWarning
당신이 메시지 속성에 액세스하는 경우 :
편집 : 무언가를 무시하거나 추가 인수를 전달하려면 다음과 같이하십시오.
class ValidationError(Exception):
def __init__(self, message, errors):
# Call the base class constructor with the parameters it needs
super(ValidationError, self).__init__(message)
# Now for your custom code...
self.errors = errors
그렇게하면 오류 메시지를 두 번째 매개 변수에 전달하고 나중에 e.errors로 가져올 수 있습니다.
또한 (.를 제외하고) 정확히 두 개의 인수를 전달해야합니다 self
. 그것은 미래의 사용자가 이해하지 못하는 흥미로운 제약입니다.
직접적으로는 Liskov의 대체 가능성을 위반 합니다.
두 가지 오류를 모두 설명하겠습니다.
>>> ValidationError('foo', 'bar', 'baz').message
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
ValidationError('foo', 'bar', 'baz').message
TypeError: __init__() takes exactly 3 arguments (4 given)
>>> ValidationError('foo', 'bar').message
__main__:1: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
'foo'
다음과 비교 :
>>> MyAppValueError('foo', 'FOO', 'bar').message
'foo'