2011-10-31 5 views
13

파이썬 모듈에서 잠재적 인 경쟁 조건을 제거하기 위해 필자는 일부 특수화 된 워크 플로를 모니터링하기 위해 파이썬의 "EAFP"코딩 스타일보다 "용서를 구하는 것이 더 쉽다"라는 것을 배웠으며 이제는 많은 사용자 지정 예외를 발생시키고 있습니다. try/except if/thens를 사용했다.얼마나 자주 파이썬에서 사용자 정의 예외를 정의해야합니까?

저는 Python을 처음 사용했습니다.이 EAFP 스타일은 논리적으로 의미가 있으며 내 코드를 더욱 견고하게 만들었지 만, 이것에 관한 어떤 것이 배 밖으로 느껴집니다. 메소드 당 하나 이상의 예외를 정의하는 것은 나쁜 습관입니까?

이러한 사용자 지정 예외는 단일 메서드에만 유용하며 기능적으로 올바른 솔루션 인 것처럼 느껴지지만 유지 관리하는 데는 많은 코드처럼 보입니다.

class UploadTimeoutFileMissing(Exception): 
    def __init__(self, value): 
     self.parameter = value 
    def __str__(self): 
     return repr(self.parameter) 

class UploadTimeoutTooSlow(Exception): 
    def __init__(self, value): 
     self.parameter = value 
    def __str__(self): 
     return repr(self.parameter) 

def check_upload(file, timeout_seconds, max_age_seconds, min_age_seconds): 

    timeout = time.time() + timeout_seconds 

    ## Check until file found or timeout 
    while (time.time() < timeout): 

     time.sleep(5) 
     try: 
      filetime = os.path.getmtime(file) 
      filesize = os.path.getsize(file) 
     except OSError: 
      print "File not found %s" % file 
      continue 

     fileage = time.time() - filetime 

     ## Make sure file isn't pre-existing 
     if fileage > max_age_seconds: 
      print "File too old %s" % file 
      continue 

     ## Make sure file isn't still uploading 
     elif fileage <= min_age_seconds: 
      print "File too new %s" % file 
      continue 

     return(filetime, filesize) 

    ## Timeout 
    try: 
     filetime 
     filesize 
     raise UploadTimeoutTooSlow("File still uploading") 

    except NameError: 
     raise UploadTimeoutFileMissing("File not sent") 
+1

Python 표준 라이브러리에는 ~ 200k 줄의 코드가 있으며 165 가지 예외가 있습니다. (나는 "[클래스 작성하기] (http://youtu.be/o9pEzgHorH0)") – Glider

답변

5

는 방법

당 하나 개 이상의 예외를 정의합니다. 그것은 나쁜 습관입니다. 동일한 오류와 관련된 두 개의 예외를 정의하지만 두 개의 다른 메소드가이를 발생시키기 때문에 두 개를 작성하는 경우에도 마찬가지입니다.

당신이 나쁜 연습 인상 여부를 묻는다면보다 더, 즉 좋은 방법입니다 다음 방법 당 하나 개의 예외보다. 그리고 오류가 같은 카테고리가 아닌 경우 모듈 당 몇 가지 예외를 정의하는 것이 좋습니다.

일반적으로 큰 모듈에 대해 하나 이상의 예외를 정의합니다. 일부 산술 라이브러리에서 작업하고 ZeroDivisionError 및 OverflowError (물론 파이썬에서는 아직 정의되지 않은 경우)를 정의하면 완벽하게 정상적으로 작동합니다.

+0

이라는 말에서 숫자를 가져 왔는데, 이는 메소드의 수와 관련하여 예외 수를 의미했을 수도 있습니다. 즉. 3 가지 방법 => 4 가지 예외, 8 가지 방법 => 11 가지 예외 – n611x007

3

메소드 당 하나 개 이상의 예외를 정의하는 나쁜 관행입니다 : 여기에

예를 들어 샘플 방법

?

예.

모듈 당 하나가 더 일반적입니다. 물론 세부적인 의미에 의존합니다. 그 질문은 다음과 같이 요약됩니다. "당신은 정말로 무엇을 잡으려고합니까?"

코드에 except ThisVeryDetailedException:을 사용하지 않으려면 매우 자세한 예외가별로 도움이되지 않습니다.

이 작업을 수행 할 수있는 경우는 매우 중요합니다. 모듈 당 하나의 예외만으로 간단하게 단순화 할 수 있으며 예외 유형이 아닌 예외의 속성으로 특수한 경우를 처리 할 수 ​​있습니다.

일반적인 제안 (모듈 당 하나, 이름은 Error)은 코드가 종종 이와 같이 보일 것임을 의미합니다.

try: 
    something 
except some_module.Error as e: 
    carry on 

이렇게하면 멋진 명명 규칙을 사용할 수 있습니다 : module.Error. 이것은 수많은 죄를 다룹니다. 관련이없는 노트에


, 당신은 당신이 "잠재적 인 경쟁 조건"을 가지고 생각한다면 당신은 아마 제대로 일을 재 설계 또는 스레드를 사용하거나 멀티로 전환하는 일을 그만해야한다. 멀티 프로세싱을 사용하면 경쟁 조건을 피하는 것이 매우 쉽다는 것을 알 수 있습니다. 당신은 예외가 실제로 다음 "메소드 본문에서"같이 방법에 따라 정의되는 것을 의미하는 경우

0

가능한 모든 시나리오에 대해 매우 구체적인 예외는 필요하지 않다고 생각합니다. 단일 UploadTimeoutError은 아마도 괜찮을 것이고 예외 문자열을 사용자 정의 할 수 있습니다. 결국 문자열이 그 것이다. Python이 구문 오류의 모든 가능한 유형에 대해 별도의 예외를 가지고 있지 않다는 것을 유의하십시오 (단지 일반 : SyntaxError).

또한 실제로 각 사용자 지정 예외에 대해 __init____str__ 메서드를 정의해야합니까? 당신이 이상한 행동을 실행하지 않는 경우 지금까지 내가 말할 수있는, 당신은 어떤 코드를 추가 할 필요가 없습니다 :

>>> class MyException(Exception): pass 
... 
>>> raise MyException("oops!") 
Traceback (most recent call last): 
    File "<ipython console>", line 1, in <module> 
MyException: oops!  
>>> str(MyException("oops!")) 
'oops!' 
3

사용자 정의 예외를 사랑하기 때문에 나는이에에 무게거야 내 심장. 나는 내 상황을 설명 할 것이고 독자는 그들 자신을 상대로 무게를 달 수있다.

저는 시각 효과 회사의 파이프 라인 설계자입니다. 제가하는 일은 대부분 내가 "시설 API"라고 부르는 것을 개발하는 것과 관련이 있습니다. 이것은 파일 시스템에서 물건을 찾지 않고, 모듈/툴/프로젝트 구성 관리, 다양한 CG 애플리케이션의 데이터 유형 처리를 통해 협업을 가능하게합니다.

필자는 파이썬의 내장 예외가 결코 터지지 않도록 노력하고 있습니다. 개발자는 기존 모듈의 생태계에 의존하여 API를 사용하여 일반적인 IOError 이스케이프 처리가 비생산적이기 때문에 - 특히 호출 루틴이 파일 시스템을 읽는 것조차 인식하지 못하기 때문에 (추상화는 다음과 같습니다. 아름다운 것). 기본 모듈이 오류에 대해 의미있는 것을 표현할 수없는 경우 더 많은 작업을 수행해야합니다.

이 문제를 해결하기위한 방법은 다른 모든 시설 예외가 파생 된 시설 예외 클래스를 만드는 것입니다. 특정 유형의 태스크 또는 특정 호스트 어플리케이션에 대한 하위 클래스가 있습니다. 오류 처리를 사용자 정의 할 수 있습니다 (예 : Maya에서 발생한 예외는 눈에 띄지 않는 콘솔에서 일반적인 예외가 발생하고 문제 해결에 도움이되는 UI를 시작합니다. 종종 놓친다.)

모든 종류의보고가 기능 예외 클래스에 내장되어 있습니다. 예외는 내부적으로보고되지 않고 사용자에게는 나타나지 않습니다. 예외 범위에 대해서는 언제든지 IM을받습니다. 다른 사람들은 최근 (일일 또는 주간) 보고서를 쿼리 할 수있는 데이터베이스에 조용히보고합니다. 각각은 일반적으로 스크린 샷, 스택 추적, 시스템 구성 등을 포함하여 사용자 세션에서 캡처 한 확장 데이터에 대한 링크입니다. 즉, 문제가보고되기 전에 효과적으로 문제를 해결할 수 있으며 대부분의 사용자가 제공 할 수있는 것보다 더 많은 정보를 손쉽게 얻을 수 있음을 의미합니다.

아주 미세한 그라디언트는 사용하지 않는 것이 좋습니다. 포맷 된 출력을 제공하기 위해 예외가 전달 된 값 (때로는 문자열 대신 사전이더라도 문제 해결을 위해 많은 데이터를 제공하려는 경우)을 허용합니다.

그래서 아니오 - 예외를 정의하거나 모듈 당 두 개를 정의하는 것이 부당하다고 생각하지 않습니다.하지만 그들은 의미 있고 프로젝트에 무언가를 추가해야합니다. IOErrorraise MyIOError("I got an IO error!")으로 감쌀 경우 다시 생각해보십시오.

관련 문제