2014-09-21 10 views
0

나는 상대적인 파이썬 초보자이며 예외를 올바르게 처리하는 방법과 혼동을 느낍니다. 바보 같은 질문에 사과.try/except /를 내부 함수 및 메인 함수와 함께 올바르게 사용하는 방법

내 main()에서 날짜 목록을 반복하고 각 날짜에 공용 웹 서버에서 CSV 파일을 다운로드하는 함수를 호출합니다. 확실한 이유로 예외를 제대로 잡으려고하지만 특히 관심있는 파일을 다운로드 할 수 있는지 여부를 알 수 없기 때문에 예외를 잡으려고합니다. 내 프로그램은 cron 작업의 일부로 실행되며 가능한 경우 3 시간마다이 파일을 다운로드하려고 시도합니다.

내가 원하는 것은 날짜 목록에서 첫 번째 파일을 다운로드하고 그 결과가 404 일 경우 목록의 가장 오래된 날짜를 사용할 수 없다고 가정하기 때문에 프로그램이 다음 파일로 진행하지 않아야합니다. 그 다음에 오는 다른 사람도 그 중 하나도 사용할 수 없습니다.

다음 파이썬 의사 코드가 있습니다. 파일을 다운로드하려고 시도하지만 함수 내부에서 예외가 발생하면 try/except 블록을 사용하지만 예외가 main()에서 제대로 처리되면 다음 날짜로 진행할지 여부를 결정할 수 있습니다. 다운로드를 수행하는 함수를 만든 이유는 나중에 다른 파일 유형의 동일한 main() 블록에서 해당 코드를 다시 사용하기 때문입니다.

def main(): 
... 
... 
# datelist is a list of date objects 
    for date in datelist: 
     download_file(date) 

def download_file(date): 
    date_string = str(date.year) + str(date.strftime('%m')) + str(date.strftime('%d')) 
    request = HTTP_WEB_PREFIX+ date_string + FILE_SUFFIX 
    try: 
     response = urllib2.urlopen(request) 
    except urllib2.HTTPError, e: 
     print "HTTPError = " + str(e) 
    except urllib2.URLError, e: 
     print "URLError = " + str(e) 
    except httplib.HTTPException, e: 
     print "HTTPException = " + str(e) 
    except IOError: 
     print "IOError = " + str(e) 
    except Exception: 
     import traceback 
     print "Generic exception: " + traceback.format_exc() 
    else: 
     print "No problem downloading %s - continue..." % (response) 
     try: 
      with open(TMP_DOWNLOAD_DIRECTORY + response, 'wb') as f: 
     except IOError: 
      print "IOError = " + str(e) 
     else: 
      f.write(response.read()) 
     f.close() 

답변

3

여기에서 핵심 개념은 문제를 해결할 수 있으면 예외를 잡아야한다는 것입니다. 할 수 없다면 처리 할 호출자의 문제입니다. 이 경우 다운로더는 파일이 없으면 문제를 해결할 수 없으므로 호출자에게 예외가 발생합니다. 호출자는 예외가있는 경우 루프를 중지해야 함을 알아야합니다. ,

for date in datelist: 
     date_string = str(date.year) + 
         str(date.strftime('%m')) + 
         str(date.strftime('%d')) 
    try: 
     download_file(date_string) 
    except: 
     e = sys.exc_info()[0] 
     print ("Error downloading for date %s: %s" % (date_string, e)) 
     break 

download_file가해야 지금 :

는 그럼 루프에 기능에서 모든 예외 처리를 이동할 수 있도록하고, 파일을 다운로드 실패가 있다면 사양이 요구하는대로, 밖으로 배변 있도록 수정 당신이 재시도 같은 것을 넣고 싶지 않다면, 단순히 예외를 잡아 두지 마세요. 당신이 발신자에 원하는대로 날짜를 디코딩 한 이후, 그 코드는 제공뿐만 아니라 download_file 나올 수있는 훨씬 더 간단

def download_file(date_string): 
    request = HTTP_WEB_PREFIX + date_string + FILE_SUFFIX 
    response = urllib2.urlopen(request) 
    print "No problem downloading %s - continue..." % (response) 
    with open(TMP_DOWNLOAD_DIRECTORY + response, 'wb') as f: 
     f.write(response.read()) 
     f.close() 
나는 print 문이 불필요하지만 당신이 만약 정말로 제안했다

그것을 원한다면 logger을 사용하는 것이보다 유연한 방법입니다. 나중에 코드 대신 설정 파일을 변경하여 원하는대로 설정하거나 해제 할 수 있습니다.

+0

아주 사려 깊은 설명. 관련된 개념을 더 잘 이해하는 데 도움이되었습니다. 알겠습니다. 고맙습니다. – codingknob

0

귀하의 질문에 대한 이해에서 ... 특정 예외가 발생할 때 실행하려는 예외 블록에 코드를 삽입해야합니다. 발생한 오류를 인쇄 할 필요가 없으며 정보를 올릴 때 필요한 느낌을 할 수 있습니다 ... 정보/옵션이있는 팝업 상자를 제공하거나 프로그램을 다음 단계로 안내 할 수 있습니다. 당신의 else 섹션은 ​​그 부분을 격리시켜야합니다. 그래서 예외가 발생하지 않을 때에 만 실행됩니다.