2011-08-09 10 views
18

Aktualnie piszę klasę opakowania. Chcę być w stanie poprawnie rejestrować wyjątki, ale pozwolić, aby metody wywoływania były świadome wyjątków, które występują. Moja klasa wygląda następująco:Wyjątek protokołowania w języku Python

import logging 

log = logging.getLogger('module') 

class MyAPIWrapper(library.APIClass): 

    def __init__(self): 
     self.log = logging.getLogger('module.myapiwrapper') 


    def my_wrapper_method(self): 
     try: 
      response = self.call_api_method() 
      return response.someData 
     except APIException, e: 
      self.log.exception('Oh noes!') 
      raise e #Throw exception again so calling code knows it happened 

jestem trochę niepewny co do połowu wyjątek i właśnie do tego dziennika, a następnie ponownie podnosząc ją tak kod wywołujący może coś z tym zrobić. Jaki jest tutaj właściwy wzór?

+0

możliwe duplikat [rejestrowanie wyjątek python] (http: // stackoverflow.com/questions/5191830/python-exception-logging) – lpapp

+0

Dokładnie to robię. Dziękujemy za przesłanie tego pytania. – smwikipedia

Odpowiedz

22

Nie ma nic złego w przechwytywaniu w dzienniku. Jednakże, polecam:

try: 
     response = self.call_api_method() 
    except APIException, e: # or 'as e' depending on your Python version 
     self.log.exception('Oh noes!') 
     raise #Throw exception again so calling code knows it happened 
    else: 
     return response.someData 

By po prostu robi gołe raise Ci zachować pełną informacje Traceback. Bardziej wyraźne jest również umieszczanie kodu, który będzie się dziać tylko wtedy, gdy nie masz wyjątku w klauzuli else, i jest bardziej zrozumiałe, z której linii przechodzisz wyjątek.

Byłoby również dobrze, gdyby klasa wywołująca wykonała rejestrowanie, jeśli mimo to obsługuje błąd, ale może to nie być wygodne dla twojej aplikacji.

Edytuj: Dokumentacja dla try ... except ... else ... finally znajduje się pod compound statements.

+0

Czy ostatnie słowo kluczowe ma być "wyjątkiem" zamiast "else", czy też ma to jakiś cel? – jlafay

+4

To powinno być "inne". Klauzula "else" ma miejsce tylko wtedy, gdy nie było wyjątku, podobnie jak klauzula 'else' w pętlach' for' i 'while' występuje tylko wtedy, gdy' break' nie został złamany. – agf

+0

Awesome! Dziękuję za wyjaśnienie. – jlafay

6

Ta metoda jest poprawna, ale zamiast raise e powinieneś po prostu użyć raise, która automatycznie ponownie podniesie ostatni wyjątek. Jest to również jeden z nielicznych przypadków, w których użycie koca except jest dopuszczalne.

Oto przykład bardzo podobny do tego, co robisz z docs Pythona na Handling Exceptions:

Ostatnim wyjątkiem klauzuli może pominąć nazwę (-y) wyjątku, aby służyć jako zamiennika. Używaj tego z dużą ostrożnością, ponieważ w ten sposób można łatwo ukryć prawdziwy błąd programowania! Może być również używany do drukowania komunikat o błędzie, a następnie ponownie podnieść wyjątek (co pozwala abonenta do obsługi wyjątku, jak również):

import sys 

try: 
    f = open('myfile.txt') 
    s = f.readline() 
    i = int(s.strip()) 
except IOError as (errno, strerror): 
    print "I/O error({0}): {1}".format(errno, strerror) 
except ValueError: 
    print "Could not convert data to an integer." 
except: 
    print "Unexpected error:", sys.exc_info()[0] 
    raise