暂停命令行python程序的简单方法?
假设我有一个Python程序,它会输出一些文本,比如:
while 1:
print "This is a line"
有没有简单的方法让我们可以按下键盘上的一个键来暂停这个循环,然后再按一次键继续运行——但如果什么都不按,它就应该自动继续?
我希望不需要使用像curses这样的复杂东西来实现这个功能!
3 个回答
0
当你按下 Ctrl+C 时,你的程序会抛出一个叫做 KeyboardInterrupt
的异常。这就像是程序收到一个“停止”的信号。你可以捕捉到这个异常,来实现你想要的效果,比如让程序暂停,然后在5秒后继续运行:
import time
while True:
try:
# This is where you're doing whatever you're doing
print("This is a line")
except KeyboardInterrupt:
print("Paused! Ctrl+C again within 5 seconds to kill program")
# A second KeyboardInterrupt that happens during this sleep will
# not be caught, so it will terminate the program
time.sleep(5)
print("Continuing...")
或者,你也可以让程序无限期地暂停,直到用户按下“回车”键:
while True:
try:
# This is where you're doing whatever you're doing
print("This is a line")
except KeyboardInterrupt:
print("Interrupted!")
input("Press enter to continue, or Ctrl+C to terminate.")
print("Continuing...")
如果你想要捕捉第二次 KeyboardInterrupt
并做一些特别的处理,你可以通过嵌套 try/except
块来实现,不过我不太推荐这样做。因为允许连续多次的 KeyboardInterrupt
来终止程序是个更好的主意。
2
对我来说,最简单的方法是,如果我在用bash的话,可以按下Control-Z来暂停正在运行的任务,然后等我准备好了再用'fg'命令把它恢复。不过因为我不知道你用的是什么平台,所以我建议你可以先试试ChristopheD的解决方案,这可能是个不错的起点。
4
你可以试试这个在Linux / Mac(还有可能其他类Unix系统)上的实现方法(代码来源:在ActiveState代码食谱上找到的)。
如果你是在Windows上工作,可以看看msvcrt。
import sys, termios, atexit
from select import select
# 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 putch(ch):
sys.stdout.write(ch)
def getch():
return sys.stdin.read(1)
def getche():
ch = getch()
putch(ch)
return ch
def kbhit():
dr,dw,de = select([sys.stdin], [], [], 0)
return dr <> []
那么,实现你想要的功能就会变成这样:
atexit.register(set_normal_term)
set_curses_term()
while True:
print "myline"
if kbhit():
print "paused..."
ch = getch()
while True
if kbhit():
print "unpaused..."
ch = getch()
break