1

예외를 처리하는 권장 방법은 예외의 원인에 따라 같은 유형이 있습니까?예외 처리 : 파이썬에서 동일한 오류 인스턴스를 구별

  • 'str' object has no attribute 'append'
  • 동시에 'float' object has no attribute 'append'

, 우리는 다른 속성 오류를 처리하지 않으려 :

의 다르게 AttributeError 다음과 같은 두 개의 인스턴스를 처리하는 하나의 욕망을 가정 해 봅시다 .

모든 예외 유형에 대해 작동하는 일반화 가능한 답변이 있습니까? 예외 객체에 대해 일부 메서드 나 함수를 사용하여 세부 정보를 얻기 위해 예외 객체를 조사 할 수 있습니까?

Try: 
    blah 
Except AttributeError as exc: 
    if exc.baz('foo') is bar: 
     handle 'str' object has no attribute 'append' 
    elif plugh(exc): 
     handle 'float' object has no attribute 'append' 
    else: 
     raise exc 

확실한 대답은 리팩터링이라고 가정합니다. 제 질문은 특히 그것이 비효율적이거나 단순히 불가능한 경우에 관한 것입니다 (그러한 사례가 전혀없는 경우).

답변

1

dir을 사용하여 개체의 메서드와 특성을 확인할 수 있습니다. 에서 파이썬 3.6에서

:

a = 'hello' 
try: 
    a.append(2) 
except AttributeError as e: 
    print(dir(e)) 

당신이 얻을 :

argswith_traceback 만 남겨두고 우리가 던더을 원하지 않기 때문에 우리가 테스트 할 수있는 일을 좁혀
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'with_traceback'] 

. 그러면 얻을 수있는 최선의 방법은 터플로 문자열을 반환하는 args을 사용하는 것입니다.

a = 'hello' 
try: 
    a.append(2) 
except AttributeError as e: 
    if 'str' in e.args[0]: 
     print('Need to handle string') 
    elif 'float' in e.args[0]: 
     print('Need to handle float') 
+0

그게 제가 두려워한 것입니다. 이전에 사용 가능한 속성으로 놀려고했습니다. 버전에 따라 다르므로'.args '에서 문자열을 사용하는 것이 바람직하지 않으며 앞으로 변경 될 수도 있습니다. 하나, 아마도, 순진한 질문 @roganjosh : 수동으로 dunder 메서드를 호출 할 수없는 이유는 무엇입니까? 또한 나는 곧 당신의 대답을 받아 들일 것이지만 누군가 다른 것을 생각해 낼 수 있도록 좀 더 기다리고 싶습니다. – Lucubrator

+1

@Lucubrator 예외를 서브 클래스 화하는 경우 원할 경우 dunder 메소드가 실제로 대체되도록 제공됩니다. 나는 이것을 직접 탐구하기 시작했다. 그러나 사용자 정의 예외 안에'if' /'elif'를 패키징하여 자체 처리 예외를 만들려고한다는 것을 깨달았습니다. 그리고 그것은 무의미한 것으로 보입니다. 'args' 문자열에 접근). 'print (e .__ 원인 __)'을 시도하십시오. 기다리는 것에 대한 걱정이 없기 때문에 재미있는 질문을 발견 했으므로 학습에도 사용했습니다. – roganjosh

+1

@Lucubrator 그리고 원하는 경우 수동으로 dunder 메소드를 호출 할 수 있습니다. 마지막 주석에서'print (e .__ cause __())'를 의미했지만 지금은 편집 할 수 없습니다. REPL에서'a = 'hello '' 그리고'a .__ str __()', 예를 들어'print (a)'를 호출하는 것과 같이 할 수 있습니다. – roganjosh