使用空格键中断计时器
Interrupting a timer with spacebar
假设我想计算我能屏住呼吸的时间,我想用 Python 来计算。我有短脚本:
start = time()
try:
while True: pass
except KeyboardInterrupt:
print(time() - start)
这具有我想要的基本功能,但它有一个致命的缺点。屏住呼吸时间长了,脑子可能会有些模糊,可能会找不到合适的位置马上按Ctrl+c,可能会丢失训练的重要数据。
空格键更容易命中。有没有一种简单的方法可以让我按下它时循环停止?
编辑:我在 OSX
您需要将控制台的键盘 (pty) 驱动程序置于原始模式。
在这个答案中有解释:
大量引用该答案:
#! /usr/bin/env python3
import sys
import termios
import time
import tty
def hold_breath(fin):
orig_setting = termios.tcgetattr(fin)
tty.setraw(fin)
start = time.time()
try:
ch = fin.read(1)[0]
assert ch == ' '
finally:
print('You lasted %.03f seconds.\r' % (time.time() - start))
termios.tcsetattr(fin, termios.TCSADRAIN, orig_setting)
if __name__ == '__main__':
print('Hit space.')
hold_breath(sys.stdin)
在 OS/X 和 Linux 上工作正常。如果您在程序恢复原始设置之前中断程序,那么 $ stty sane
就是您的朋友。
import sys
import termios
import contextlib
SPACE_BAR = 32
@contextlib.contextmanager
def raw_mode(file):
old_attrs = termios.tcgetattr(file.fileno())
new_attrs = old_attrs[:]
new_attrs[3] = new_attrs[3] & ~(termios.ECHO | termios.ICANON)
try:
termios.tcsetattr(file.fileno(), termios.TCSADRAIN, new_attrs)
yield
finally:
termios.tcsetattr(file.fileno(), termios.TCSADRAIN, old_attrs)
def main():
print 'exit with spacebar'
with raw_mode(sys.stdin):
try:
while True:
if sys.stdin.read(1) == chr(SPACE_BAR):
break
except (KeyboardInterrupt, EOFError):
pass
if __name__ == '__main__':
main()
答案取决于您的OS。在 Windows 上,这将在任何按键按下时停止,但您可以查看 msvcrt.getch()
的 return 值以确定它是否为 space。现在当你昏倒并且你的脸碰到键盘时它会停止在任何键上。
import time
import msvcrt
start = time.time()
while not msvcrt.kbhit(): # Indicates a key is waiting to be read
pass
end = time.time()
msvcrt.getch() # read and (in this case) throw away the key press.
print(end-start)
假设我想计算我能屏住呼吸的时间,我想用 Python 来计算。我有短脚本:
start = time()
try:
while True: pass
except KeyboardInterrupt:
print(time() - start)
这具有我想要的基本功能,但它有一个致命的缺点。屏住呼吸时间长了,脑子可能会有些模糊,可能会找不到合适的位置马上按Ctrl+c,可能会丢失训练的重要数据。
空格键更容易命中。有没有一种简单的方法可以让我按下它时循环停止?
编辑:我在 OSX
您需要将控制台的键盘 (pty) 驱动程序置于原始模式。
在这个答案中有解释:
大量引用该答案:
#! /usr/bin/env python3
import sys
import termios
import time
import tty
def hold_breath(fin):
orig_setting = termios.tcgetattr(fin)
tty.setraw(fin)
start = time.time()
try:
ch = fin.read(1)[0]
assert ch == ' '
finally:
print('You lasted %.03f seconds.\r' % (time.time() - start))
termios.tcsetattr(fin, termios.TCSADRAIN, orig_setting)
if __name__ == '__main__':
print('Hit space.')
hold_breath(sys.stdin)
在 OS/X 和 Linux 上工作正常。如果您在程序恢复原始设置之前中断程序,那么 $ stty sane
就是您的朋友。
import sys
import termios
import contextlib
SPACE_BAR = 32
@contextlib.contextmanager
def raw_mode(file):
old_attrs = termios.tcgetattr(file.fileno())
new_attrs = old_attrs[:]
new_attrs[3] = new_attrs[3] & ~(termios.ECHO | termios.ICANON)
try:
termios.tcsetattr(file.fileno(), termios.TCSADRAIN, new_attrs)
yield
finally:
termios.tcsetattr(file.fileno(), termios.TCSADRAIN, old_attrs)
def main():
print 'exit with spacebar'
with raw_mode(sys.stdin):
try:
while True:
if sys.stdin.read(1) == chr(SPACE_BAR):
break
except (KeyboardInterrupt, EOFError):
pass
if __name__ == '__main__':
main()
答案取决于您的OS。在 Windows 上,这将在任何按键按下时停止,但您可以查看 msvcrt.getch()
的 return 值以确定它是否为 space。现在当你昏倒并且你的脸碰到键盘时它会停止在任何键上。
import time
import msvcrt
start = time.time()
while not msvcrt.kbhit(): # Indicates a key is waiting to be read
pass
end = time.time()
msvcrt.getch() # read and (in this case) throw away the key press.
print(end-start)