Programdan çıkmadan önce bir şeyler yapmak


102

Programınız kapanmadan önce çalıştırılacak bir işleve veya bir şeye nasıl sahip olabilirsiniz? Arka planda sürekli çalışan bir komut dosyam var ve bazı verileri çıkmadan önce bir dosyaya kaydetmem gerekiyor. Bunu yapmanın standart bir yolu var mı?


2
Komut dosyası asla durmamalıdır, ancak belki birisi işlemi öldürebilir veya Ctrl + \ veya başka bir şeye basabilir.
RacecaR

Yanıtlar:


167

atexitModüle göz atın :

http://docs.python.org/library/atexit.html

Örneğin, uygulamam sona ererken bir mesaj yazdırmak istersem:

import atexit

def exit_handler():
    print 'My application is ending!'

atexit.register(exit_handler)

Bunun betiğin normal sonlandırılması için harika çalıştığını unutmayın, ancak her durumda çağrılmayacaktır (örn. Önemli dahili hatalar).


6
Ctrl + C veya Ctrl + \ tuşlarına basarsanız çağrılacağı yerde yapmanın bir yolu var mı?
RacecaR

8
Ctrl + C tuşlarına basarsanız aranacaktır. Bu sadece bir KeyboardInterrupt istisnası oluşturur.
Ned Batchelder

1
Oh, bunu unuttum. Ve birisi python işlemini doğru bir şekilde öldürürse yapabileceğiniz hiçbir şeyin çalışmayacağını varsayıyorum.
RacecaR

5
@RacecaR: gerçekten; Bir süreci öldürmenin amacı, onu ölmesini engellemektir. Dokümanlar: Note The exit function is not called when the program is killed by a signal, when a Python fatal internal error is detected, or when os._exit() is called.
Katriel

18
@RacecaR, bir işlem kötü bir şekilde çökse veya acımasızca öldürülse bile sonlandırma kodunu çalıştırmanın tek yolu , tek işi hedef süreci göz önünde bulundurmak olan "monitör" veya "bekçi köpeği" olarak bilinen başka bir süreçtir. uygun olduğunda sonlandırma kodunu çalıştırın. Tabii ki çok farklı bir mimari gerektirir ve sınırlamaları vardır; Böyle bir işlevselliğe ihtiyacınız varsa, konuyla ilgili farklı bir Q açmanız en iyisidir.
Alex Martelli

32

Bir şeyin hatalarda bile her zaman çalışmasını istiyorsanız, try: finally:bunun gibi kullanın -

def main():
    try:
        execute_app()
    finally:
        handle_cleanup()

if __name__=='__main__':
    main()

İstisnaları da işlemek istiyorsanız except:,finally:


14
İşlemin sona ermesi nedeniyle SIGTERM oluştuğunda çalışmaz.
ramu

16

Komut dosyasını a yükselterek durdurursanız KeyboardInterrupt(örneğin Ctrl-C tuşlarına basarak), bunu standart bir istisna olarak yakalayabilirsiniz. SystemExitAynı şekilde yakalayabilirsiniz .

try:
    ...
except KeyboardInterrupt:
    # clean up
    raise

Bunu bilmeniz için söylüyorum; Bunu yapmanın 'doğru' yolu atexityukarıda bahsedilen modüldür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.