PyCharm IDE를 사용할 때 except:
예외 유형없이를 사용 하면 IDE에서이 예외 절이 Too broad
.
이 조언을 무시해야합니까? 아니면 항상 예외 유형을 지정하는 것이 Pythonic입니까?
PyCharm IDE를 사용할 때 except:
예외 유형없이를 사용 하면 IDE에서이 예외 절이 Too broad
.
이 조언을 무시해야합니까? 아니면 항상 예외 유형을 지정하는 것이 Pythonic입니까?
답변:
거의 항상 명시적인 예외 유형을 지정하는 것이 좋습니다. 네이 키드 except:
절 을 사용하면 잡을 것으로 예상되는 것 이외의 예외를 잡을 수 있습니다. 이것은 버그를 숨기거나 예상 한대로 수행하지 않을 때 프로그램을 디버그하기 어렵게 만들 수 있습니다.
예를 들어, 데이터베이스에 행을 삽입하는 경우 행이 이미 존재 함을 나타내는 예외를 포착하여 업데이트를 수행 할 수 있습니다.
try:
insert(connection, data)
except:
update(connection, data)
bare를 지정 except:
하면 데이터베이스 서버가 넘어 졌음을 나타내는 소켓 오류도 포착됩니다. 처리하는 방법을 알고있는 예외 만 포착하는 것이 가장 좋습니다. 프로그램이 계속해서 예기치 않은 방식으로 작동하는 것보다 예외 시점에서 실패하는 것이 더 낫습니다.
베어를 사용하고 싶은 한 가지 경우 except:
는 네트워크 서버처럼 항상 실행해야하는 프로그램의 최상위 수준에 있습니다. 하지만 예외를 기록하는 데 매우주의해야합니다. 그렇지 않으면 무엇이 잘못되었는지 알아낼 수 없습니다. 기본적으로이 작업을 수행하는 프로그램에는 최대 한 곳만 있어야합니다.
이 모든에 대한 추론 코드를하지 않을해야한다는 것입니다 raise Exception('some message')
그것을 사용하는 클라이언트 코드를 강제하기 때문에 except:
(또는 except Exception:
어떤 거의 나쁜로). 신호를 보내려는 문제에 특정한 예외를 정의해야합니다 ( ValueError
또는 같은 일부 내장 예외 하위 클래스에서 상속 될 수 있음 TypeError
). 또는 특정 내장 예외를 발생시켜야합니다. 이를 통해 코드 사용자는 처리하려는 예외 만 포착 할 때주의 할 수 있습니다.
except:
또한 catches (다른 많은 것 중에서) NameError
및 AttributeError
, 따라서 try
블록 에서 철자를 잘못 입력하면 (예 : "insert"함수가 실제로 필요한 insert_one
만큼 일관성을 중요하게 생각하지 않았기 때문에 호출 됩니다), 항상 조용히 시도합니다 update()
.
main()
)?
except Exception:
잡을 것입니다 NameError
및 AttributeError
도. except:
나쁘게 만드는 것은 비즈니스가 걸리지 않는 물건을 잡는다는 것입니다. 예를 들어 SystemExit
( exit
또는 을 호출 할 때 발생 sys.exit
하고 이제 의도 한 이탈을 막았습니다) 그리고 KeyboardInterrupt
(다시 말하지만, 사용자가을 눌렀 Ctrl-C
다면 아마도 원하지 않을 것입니다. 그들을 괴롭히기 위해 계속 달리기 위해). 후자 만이 실제로 잡을 수 있으며 명시 적으로 잡아야합니다. 적어도이 except Exception:
두 가지가 정상적으로 전파되도록합니다.
통역사가 제공하는 조언을 무시해서는 안됩니다.
로부터 PEP-8 파이썬 스타일 가이드 :
예외를 잡을 때, 제외 : 절을 사용하는 대신 가능하면 특정 예외를 언급하십시오.
예를 들어 다음을 사용하십시오.
try:
import platform_specific_module
except ImportError:
platform_specific_module = None
bare except : 절은 SystemExit 및 KeyboardInterrupt 예외를 포착하여 Control-C로 프로그램을 중단하기 어렵게 만들고 다른 문제를 위장 할 수 있습니다. 프로그램 오류를 알리는 모든 예외를 포착하려면 except Exception :을 사용하십시오 (bare except는 BaseException :을 제외하는 것과 동일합니다).
경험상 가장 좋은 방법은 'except'절의 사용을 두 가지 경우로 제한하는 것입니다.
예외 처리기가 트레이스 백을 인쇄하거나 기록하는 경우; 최소한 사용자는 오류가 발생했음을 알게됩니다. 코드가 일부 정리 작업을 수행해야하지만 예외가 발생하여 위로 전파되도록합니다. try ... finally는이 경우를 처리하는 더 좋은 방법이 될 수 있습니다.
파이썬에만 국한되지 않습니다.
예외의 요점은 가능한 한 문제가 발생한 위치에 가깝게 문제를 처리하는 것입니다.
따라서 예외적 인 상황에서 문제를 유발할 수있는 코드와 해결 방법을 서로 "다음"으로 유지할 수 있습니다.
문제는 코드에서 발생할 수있는 모든 예외를 알 수 없다는 것입니다. 당신이 알 수있는 것은 만약 그것이 파일을 찾을 수 없다는 예외라면, 당신은 그것을 트랩하고 사용자에게 함수를 가져 오거나 취소하도록 프롬프트 할 수 있다는 것입니다.
try catch를 넣으면 파일 루틴 (읽기 전용, 권한, UAC, 실제로는 pdf가 아닌 등)에 어떤 문제가 있더라도 모든 파일이 catch를 찾을 수 없으며 사용자가 파일에 드롭됩니다. "하지만 거기에,이 코드는 쓰레기"라고 외치고 있습니다.
이제 모든 것을 잡을 수있는 몇 가지 상황이 있지만 의식적으로 선택해야합니다.
그들은 캐치, 일부 로컬 작업 (예 : 리소스 생성 또는 잠금 (예 : 쓰기 위해 디스크에서 파일 열기))을 실행 취소 한 다음 예외를 다시 throw하여 상위 수준에서 처리합니다.
다른 하나는 왜 그것이 잘못되었는지 상관하지 않는다는 것입니다. 예를 들어 인쇄. 프린터에 문제가 있습니다. 문제를 해결하고 응용 프로그램을 종료하지 마십시오. 코드가 일종의 일정을 사용하여 일련의 개별 작업을 실행했다면 비슷한 헛된 일이지만 작업 중 하나가 실패했기 때문에 전체가 죽기를 원할 것입니다.
참고 위의 작업을 수행하면 일종의 예외 로깅 (예 : catch log end)을 권장 할 수 없습니다.
항상 같은 당신이 캐치하지 않으려는 많은 유형이있다, 예외 유형을 지정 SyntaxError
, KeyboardInterrupt
, MemoryError
등
except Exception:
하면 우리가 잡고 싶지 않은 위의 유형을 피할 수 있습니까?
except Exception
괜찮습니다.
except Exception
캐치 SyntaxError
및 MemoryError
기본 클래스이기 때문입니다. KeyboardInterrupt
, SystemExit
(에 의해 발생 sys.exit()
) 포착되지 않음 (즉시 BaseException 하위 클래스 임)
내가 사용하는 곳은 다음과 같습니다.
이것이 확인되지 않은 예외에 대한 내 코드의 주요 용도입니다.
나는 항상 이것을 추가하여 프로덕션 코드가 스택 트레이스를 유출하지 않도록합니다.
두 가지 방법이 있습니다.
이 방법을 선호합니다. 어떤 예외가 적절하게 포착되어야하는지 더 쉽게 감지 할 수 있습니다. 낮은 수준의 예외가 더 높은 수준에서 기록 될 때 문제를 더 잘 볼 수 있습니다.
일부 동료는 이러한 방식을 선호합니다. 이는 하위 수준 기능에서 하위 수준 예외를 유지하기 때문에 "속한다".