Timeout when invoking IPython embed()

白昼怎懂夜的黑 提交于 2019-12-11 04:22:51

问题


Is there a way to have a timeout when calling IPython.embed() in a python script? Say I have a script that stops for a IPython.embed() at various places, how can I let the script go on with its business when the user doesn't respond in time?


回答1:


This is not quite an answer to the question, but it is adequate for what I wanted.

I used some cross-platform keypress timeout code from

  • https://stackoverflow.com/a/23098294/1490584, and
  • https://stackoverflow.com/a/5047058/1490584

to let the user decide within a time window if a IPython.embed() should be called:

import time
import IPython

try:
    from msvcrt import kbhit
except ImportError:
    import termios, fcntl, sys, os
    def kbfunc():
        fd = sys.stdin.fileno()
        oldterm = termios.tcgetattr(fd)
        newattr = termios.tcgetattr(fd)
        newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
        termios.tcsetattr(fd, termios.TCSANOW, newattr)
        oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
        fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
        try:
            while True:
                try:
                    c = sys.stdin.read(1)
                    return c.decode()
                except IOError:
                    return False
        finally:
            termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
            fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
else:
    import msvcrt
    def kbfunc():
        #this is boolean for whether the keyboard has bene hit
        x = msvcrt.kbhit()
        if x:
            #getch acquires the character encoded in binary ASCII
            ret = msvcrt.getch()
            return ret.decode()
        else:
            return False

def wait_for_interrupt(waitstr=None, exitstr=None, countdown=True, delay=3):
    if waitstr is not None: print(waitstr)
    for i in range(delay*10):
        if   countdown and i%10 ==0    : print('%d'%(i/10 + 1), end='')
        elif countdown and (i+1)%10 ==0: print('.')
        elif countdown                 : print('.', end='')

        key = kbfunc()
        if key: return key
        time.sleep(0.1)
    if exitstr is not None: print(exitstr)
    return False

if __name__ == "__main__":
    #wait_for_interrupt example test
    if wait_for_interrupt('wait_for_interrupt() Enter something in the next 3 seconds', '... Sorry too late'):
        IPython.embed()

    #begin the counter
    number = 1

    #interrupt a loop
    while True:

        #acquire the keyboard hit if exists
        x = kbfunc() 

        #if we got a keyboard hit
        if x != False and x == 'i':
            #we got the key!
            IPython.embed()
            #break loop
            break
        else:
            #prints the number
            print(number)
            #increment, there's no ++ in python
            number += 1
            #wait half a second
            time.sleep(0.5)


来源:https://stackoverflow.com/questions/26693852/timeout-when-invoking-ipython-embed

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!