连续循环并退出python

时间:2010-10-01 04:51:40

标签: python continuous

我有一个脚本,在调用时连续运行,每5分钟检查一次我的Gmail收件箱。为了让它每5分钟运行一次,我使用的是time.sleep()函数。但是我希望用户在按下q时随时结束脚本,这在使用time.sleep()时似乎无法完成。关于我如何做到这一点的任何建议?

阿里

3 个答案:

答案 0 :(得分:3)

您可以在sys.stdin上使用select()并结合超时。粗略地说,你的主循环看起来像这样(未经测试):

while True:
    r,w,e = select.select([sys.stdin], [], [], 600)
    if sys.stdin in r: # data available on sys.stdin
        if sys.stdin.read() == 'q':
            break
    # do gmail stuff

为了能够从stdin读取单个字符,您需要将stdin置于无缓冲模式。另一种描述是here。如果你想保持简单,只需要用户在'q'

之后按Enter键

我之前提到的-u标志不起作用:它可能将pyton置于无缓冲模式但不是终端。

或者,ncursus在这里可能会有所帮助。我只是暗示,我对此没有多少经验;如果我想要一个精美的用户界面,我会使用TkInter。

答案 1 :(得分:1)

确定。尝试这个python代码...(在linux中测试。大多数可能不会在Windows上工作 - 感谢Aaron对此的输入)

这是从http://code.activestate.com/recipes/572182-how-to-implement-kbhit-on-linux/

派生(复制和修改)的
import sys, termios, atexit
from select import select

delay = 1 # in seconds - change this for your needs

# save the terminal settings
fd = sys.stdin.fileno()
new_term = termios.tcgetattr(fd)
old_term = termios.tcgetattr(fd)

# new terminal setting unbuffered
new_term[3] = (new_term[3] & ~termios.ICANON & ~termios.ECHO)

# switch to normal terminal
def set_normal_term():
    termios.tcsetattr(fd, termios.TCSAFLUSH, old_term)

# switch to unbuffered terminal
def set_curses_term():
    termios.tcsetattr(fd, termios.TCSAFLUSH, new_term)

def getch():
    return sys.stdin.read(1)

def kbhit():
    dr,dw,de = select([sys.stdin], [], [], delay)
    return dr <> []

def check_mail():
    print 'Checking mail'

if __name__ == '__main__':
    atexit.register(set_normal_term)
    set_curses_term()

    while 1:
        if kbhit():
            ch = getch()
            break
        check_mail()

    print 'done'

答案 2 :(得分:0)

如果你真的想(并且想浪费大量资源),你可以将你的循环切成200毫秒的块。所以睡200毫秒,检查输入,重复直到五分钟,然后检查你的收件箱。不过我不推荐它。

虽然它正在睡觉,但是过程被阻止,并且在睡眠结束之前不会接收输入。

哦,作为一个补充说明,如果你在键睡觉时按下键,它仍应进入缓冲区,因此当睡眠结束并最终读取输入时,它将被拉出,IIRC。