2013-03-11 14 views
11

Z bloku __exit__ w niestandardowej klasie kursora chcę przechwycić wyjątek, dzięki czemu mogę z kolei podać bardziej szczegółowy wyjątek. Jaki jest właściwy sposób na zrobienie tego?Ponownie przypisz wyjątek z poziomu pythona __exit__ blok

class Cursor: 
    def __enter__(self): 
     ... 

    def __exit__(self, ex_type, ex_val, tb): 
     if ex_type == VagueThirdPartyError: 
      # get new more specific error based on error code in ex_val and 
      # return that one in its place. 
      return False # ? 
     else: 
      return False 

Podniesienie specyficzny wyjątek w bloku __exit__ Wygląda hack, ale może jestem na myśli to.

+0

Dlaczego wydaje się być hackem, aby podnieść wyjątek? – NPE

+1

Pomyślałem, że mógł być inny sposób, aby to zrobić, ponieważ menedżer kontekstu przechwytuje wszystkie wyjątki w obrębie głównego bloku, przechowuje go, a następnie przekazuje do __exit__ w celu zatwierdzenia lub zawetowania. Podnoszenie się w ciągu __exit__ wydawało się bardziej rozszerzeniem zakresu obowiązków na podstawie jego argumentów - ale wyraźnie nad tym myślałem. – jpredham

Odpowiedz

16

Właściwą procedurą jest podniesienie nowego wyjątku wewnątrz procedury obsługi __exit__.

Powinieneś nie podnieść wyjątek, który został przekazany; aby umożliwić powiązanie menedżera kontekstu, w takim przypadku powinieneś po prostu zwrócić wartość Falseya z obsługi. Podnoszenie własnych wyjątków jest jednak całkowicie w porządku.

Należy pamiętać, że lepiej jest używać testu w celu sprawdzenia tożsamości is typ przeszedł w wyjątkiem:

def __exit__(self, ex_type, ex_val, tb): 
    if ex_type is VagueThirdPartyError: 
     if ex_val.args[0] == 'foobar': 
      raise SpecificException('Foobarred!') 

     # Not raising a new exception, but surpressing the current one: 
     if ex_val.args[0] == 'eggs-and-ham': 
      # ignore this exception 
      return True 

     if ex_val.args[0] == 'baz': 
      # re-raise this exception 
      return False 

    # No else required, the function exits and `None` is returned 

Można również użyć issubclass(ex_type, VagueThirdPartyError) aby umożliwić podklasy określonego wyjątku.

+4

A może: 'if issubclass (ex_type, VagueThirdPartyError)' – mgilson

+1

** tl; dr ** dla pracowników Google: niestandardowe '__exit__' nie propaguje wyjątków? Nie zwracaj niczego/zwróć wartość falsey. – Qix

Powiązane problemy