2017-08-20 15 views
0

私はctrl-cを押すと、プロンプトが画面上にポップアップし、プログラムを実行したままにしておきたいが、プログラムは終了するので、私は を入力しない。 どこが間違っていますか?この機能は可能ですか?KeyboardInterruptでプログラムを終了することを確実にしているかどうかを確認する方法を教えてください。

from functools import wraps 
import sys 

class CleanExit(object): 
    def __init__(self, *args, **kw): 
     # You can supply an optional function 
     # to be called when the KeyboardInterrupt 
     # takes place. 
     # If the function doesn't require any arguments: 
     #  @CleanExit(handler=func) 
     # If the function requires arguments: 
     #  @CleanExit('foo', handler=handle) 

     self.kw = kw 
     self.args = args 
     self.handler = kw.get('handler') 

    def __call__(self, original_func): 
     decorator_self = self 
     @wraps(original_func) 
     def wrappee(*args, **kwargs): 
      try: 
       original_func(*args,**kwargs) 
      except KeyboardInterrupt: 
       if self.handler: 
        self.handler(*self.args) 
       else: 
        sys.exit(0) 
     return wrappee 

def handle(): 
    answer = raw_input("Are you sure you want to exit?").lower().strip() 
    if 'y' in answer: 
     sys.exit(0) 

@CleanExit(handler=handle) 
def f(): 
    while 1: pass 

f() 

答えて

2

あなたの問題は、処理後に機能を続けるために何もしていないということです。あなたのコードが割り込みを処理し、とにかく終了します。ハンドラが終了した場合は、再帰的にこのように成功wrappeeを再入力することができます

def __call__(self, original_func): 
     decorator_self = self 
     @wraps(original_func) 
     def wrappee(*args, **kwargs): 
      try: 
       original_func(*args,**kwargs) 
      except KeyboardInterrupt: 
       if self.handler: 
        self.handler(*self.args) 
        wrappee(*args, **kwargs) 
       else: 
        sys.exit(0) 
     return wrappee 

は今、この作業をする必要があります。 Pythonはテールコールを最適化できないので、より多くの場合、 sys.getrecursionlimit()よりも多くの場合、Pythonはスタックフレームを使い果たし、クラッシュします。

編集:それは愚かだった - それについて考えて、この機能は手で削除することは非常に些細なので、おそらくカウントされません。

def __call__(self, original_func): 
     decorator_self = self 
     @wraps(original_func) 
     def wrappee(*args, **kwargs): 
      while True: 
       try: 
        original_func(*args,**kwargs) 
       except KeyboardInterrupt: 
        if self.handler: 
         self.handler(*self.args) 
        else: 
         sys.exit(0) 
     return wrappee 

も正常に動作するはずです。

関連する問題