通过命令行进行条件按键
通过命令行进行条件按键
我正在构建一个测试用例,想要通过按键来启动或停止一个计时器,但是我无法找出如何保持我的例程运行... 'g' 应该启动计时器(并不断重复),'s' 应该停止计时器。'g' 然后可以重新启动计时器,等等。然而,'g' 启动计时器,但 's' 没有任何作用。我做错了什么?
代码:
#!/usr/bin/env python import time, sys def print_something(status): while(status): print '当前时间: ' , time.ctime() time.sleep(1); def main(): result = 1 print '开始时间: ' , time.ctime() result = raw_input('按下 g 启动计时器,按下 s 停止.\n') while(result is 'g'): print_something(True) result = '' result = None time.stop() main()
问题的出现原因是代码中的while循环没有放在main函数中,导致代码无法正常运行。解决方法是将while循环放在main函数中。
下面是修改后的代码:
import time import sys def main(): result = 1 print('starting time: ', time.ctime()) while(result): result = input('press g to start timer, s to stop.\n') if result == 'g': print_something() result = '' elif result == 's': result = None time.stop() sys.exit() def print_something(): # 这里是要执行的代码 print('Printing something...') if __name__ == '__main__': main()
更新:
你尝试过使用while(result != 's')
进行测试吗?
我尝试过这样修改代码,但是代码无法运行。我将更新我的问题。
问题的原因是代码中的控制流程被卡在了print_something函数中,而该函数是一个无限循环,导致无法离开该函数。换句话说,虽然你想读取用户输入的's',但是直到循环结束,这部分代码都不会被执行。
解决方法是需要一种中断机制。下面的代码实现了你想要的功能,但是用户需要按下"Ctrl+C"来停止计时器。
#!/usr/bin/env python import time, sys def main(): result = 1 print 'starting time: ' , time.ctime() while(result): result = raw_input('press g to start timer, ctrl+c to stop.\n') if result is 'g': print_something() result = '' else: result = None time.stop() sys.exit() def print_something(): while 1: try: print 'the time: ' , time.ctime() time.sleep(1); except KeyboardInterrupt: break main()
编辑部分提到了编程范式需要改变。你需要一个响应事件(例如按键)的事件驱动程序。也许你需要创建一个线程,来获取用户按下的键并根据按下的键执行相应的操作,同时另一个线程打印时间。
去掉代码中的sys.exit()行将只停止计时器,并且你可以添加更多代码来执行其他操作。
然后将else改为elif result is 's',这样只有在从命令行获取到's'后(在按下ctrl-c后)才会执行sys.exit()。
可以通过子进程或类似的方法来实现这一点。你提到的关于创建线程的建议是一个很好的答案,但是我不知道如何做到。我会研究一下。
确实,我可以编写处理线程的代码,就像我在上面的编辑中提到的那样,这不是问题。我不熟悉的是如何确定在Python中按下了哪个键。这个主题在这里讨论:stackoverflow.com/questions/694296/…。它取决于你想要使用的平台,也许你可以使用PyKeylogger。
你不能只使用raw_input()吗?我在osx上;我会更新标签。
在命令行中工作时,你不能只使用raw_input(),因为屏幕不会更新(也就是不会打印任何内容),直到用户输入了一些内容。换句话说,程序会一直等待用户输入,而不会(持续)打印时间。
我将这个回答标记为正确的,因为我认为它是“最接近正确的”。我的原始问题涉及到命令行键盘输入,我认为在给定的原始参数下,没有一种简单的方法来实现它。由于问题的范围已经改变,我将在以后的某个时候发布关于线程/子进程管理的另一个问题,当我实现了一些测试时。
顺便说一下,如果s键对你想要做的事情不重要,你可以创建一个无限循环,每次输入g时启动计时器,每次按下Ctrl+C时停止计时器。