2012-01-26 2 views
6

böyle Python şey bazı kod yazıyorum: Ben döngü kesme çalıştığınızdaPython'da, bir fonksiyonun KeyboardInterrupt ve SystemExit'i yakalamasını engelleyebilir miyim?

import sys 
try: 
    for x in large_list: 
     function_that_catches_KeyboardInterrupt(x) 
except KeyboardInterrupt: 
    print "Canceled!" 
    sys.exit(1) 

, temelde aşağı Kontrol fonksiyonunun her çağırmayı iptal için yeterince uzun + C tutmak gerekir large-list'un tüm öğeleri için, ve sonra programımın çıkışı var.

Bu işlevin, kendimi yakalayabilmem için KeyboardInterrupt'ı yakalamasını engelleyebileceğim bir yol var mı? Düşünebildiğim tek yol, yalnızca işlevin çağrılması için ayrı bir iş parçacığı oluşturarak iş parçacığını kötüye kullanmak olurdu, ama bu aşırı görünüyor.

Düzenleme: söz konusu kodu (Ben kolayca değiştiremezsiniz olan) kontrol ve aslında çıplak except: kullanır, bu nedenle bile sys.exit(1) bir SystemExit istisna olarak yakalanır. Çıplak except: bloğundan nasıl çıkıp programdan çıkarım?

+0

Bu benim için aşırı bir şey gibi görünmüyor ... çünkü ortaya çıkabilecek diğer her şey bir çeşit siyahı içerebiliyor büyü ... – GaretJax

+0

Her bir çağrı için bir iş parçacığı kullanmanıza gerek olmadığını unutmayın, yalnızca bir tanesi yeterlidir. ;-) – GaretJax

cevap

6

SIGINT işleyicisini signal kitaplığını kullanarak yeniden isimlendirebilirsiniz.

import signal, sys 
def handler(signal, frame): 
    print "Canceled!" 
    sys.exit(1) 
signal.signal(signal.SIGINT, handler) 
for x in large_list: 
    function_that_catches_KeyboardInterrupt(x) 

SystemExit yakalanma zaman biri çıkabilirsiniz birkaç yolu vardır. os._exit(1), temizlemeden c tarzı bir çıkış yapacak. os.kill(os.getpid(), signal.SIGTERM), tercümanın bir miktar temizlik yapmasına izin verecek, bence dosya kulplarının vb. Fışkırtma/kapanmalarına inanıyorum.

+0

Sanırım sinyalin dış istisna eylemcisi tarafından yakalanmasını istiyor - yine de sadece işlevin içindeki kodla değil. Bu, tamamen –

+0

'u bastırır. Daha sonra sys.exit çağrısını elleriyle programına geri döndürecek bir şeyle değiştirebilir. Akış kontrolü ele geçirme ile uğraşıyorsunuz, daha zarif bir çözüm bulacağınızı sanmıyorum;) – stefan

+0

'sys.exit' yerine' 'KeyboardInterrupt()' tuşunu kaldırabilir miyim? Yoksa farklı bir istisna mı kullanmalıyım? –