2008-09-18 13 views
10

Krótko mówiąc, mam znaczącą aplikację Python, która między innymi wykracza na "stracenie", "montowanie" itp. W systemie Linux. Zasadniczo zużywa zasoby systemowe, które muszą zostać zwolnione po ukończeniu.Czy ma zastosowanie obsługa wyjątków dla całej aplikacji?

Jeśli moja aplikacja ulegnie awarii, chcę się upewnić, że zasoby systemowe zostały poprawnie zwolnione.

Czy ma sens wykonanie następujących czynności?

def main(): 
    # TODO: main application entry point 
    pass 

def cleanup(): 
    # TODO: release system resources here 
    pass 

if __name__ == "__main__": 
    try: 
     main() 
    except: 
     cleanup() 
     raise 

Czy jest to zazwyczaj wykonywane? Czy istnieje lepszy sposób? Być może destruktor w klasie singleton?

Odpowiedz

11

Generalnie podoba mi się obsługa wyjątków najwyższego poziomu (niezależnie od języka). Są doskonałym miejscem do czyszczenia zasobów, które mogą nie być bezpośrednio związane z zasobami zużywanymi w metodzie, która zgłasza wyjątek.

To także fantastyczne miejsce na log tych wyjątków, jeśli takie ramy są na miejscu. Operatory najwyższego poziomu wychwycą te dziwaczne wyjątki, których nie planowałeś i pozwolą ci je poprawić w przyszłości, w przeciwnym razie możesz nigdy o nich nie wiedzieć.

Należy uważać, aby operator najwyższego poziomu nie zgłaszał wyjątków!

+0

Obsługa wyjątków najwyższego poziomu jest przydatna w aplikacjach GUI. Nieprzeniknione wyjątki generowane w procedurach obsługi zdarzeń pojawią się w konsoli, ale generalnie nie spowodują awarii programu (np. W PyGTK i PyQt), może to pozostać niezauważone. Jeśli wyświetlisz okno dialogowe błędu w module obsługi, nie masz tego problemu. –

+0

Proponuję również, aby umieścić je w aplikacjach konsolowych, które przetwarzają wsadowo. Mam je wysłać e-mail, abyśmy mogli być powiadamiani o wszelkich problemach, ale przynajmniej mógł to zarejestrować. –

2

Szeroka obsługa aplikacji jest w porządku. Są świetne do logowania. Upewnij się tylko, że aplikacja jest trwała i mało prawdopodobne jest, że ulegnie awarii.

7

Destruktor (jak w metodzie __del__) jest złym pomysłem, ponieważ nie ma gwarancji, że zostanie wywołany. Moduł atexit jest bezpieczniejszym podejściem, chociaż te nadal nie będą uruchamiane, jeśli interpreter Pythona ulegnie awarii (zamiast aplikacji Python), lub gdy os._exit() zostanie użyty lub proces zostanie zabity agresywnie, lub gdy urządzenie uruchomi się ponownie. (Oczywiście, ostatni element nie jest problemem w twoim przypadku.) Jeśli twój proces jest podatny na awarie (na przykład używa on zmiennego modułu rozszerzenia innej firmy), możesz wykonać czyszczenie w prostym procesie nadrzędnym dla więcej izolacji.

Jeśli nie martwisz się, użyj modułu atexit.

+0

Nie byłem całkowicie pewien, czy destruktor zostanie wywołany. Dziękuję za wyjaśnienie! Wygląda na to, że potrzebuję czegoś, czego brakuje. – EmmEff

1

To wydaje się rozsądnym podejściem, bardziej prostym i niezawodnym niż destruktor w klasie singleton. Możesz również zajrzeć do modułu "atexit". (Wymawiane "na wyjściu", a nie "a tex it" lub coś w tym stylu.) Myliłem to przez długi czas.)

2

jeśli używasz klas, powinieneś uwolnić zasoby, które przydzielą w swoich destruktorach, oczywiście . Użyj polecenia try: na całej aplikacji, jeśli chcesz zwolnić zasoby, które nie zostały jeszcze uwolnione przez destruktory klas.

I zamiast używać catch-all wyjątkiem :, należy użyć następujący blok:

try: 
    main() 
finally: 
    cleanup() 

który zapewni porządki w bardziej pythonic sposób.

1

Należy rozważyć napisanie menedżera kontekstu i użycie instrukcji with.