我正在尝试编写一个while循环,通过使用os.system(“clear”)不断更新屏幕,然后每隔几秒打印一个不同的文本消息。如何在循环期间获得用户输入? raw_input()只是暂停和等待,这不是我想要的功能。
import os
import time
string = "the fox jumped over the lazy dog"
words = string.split(" ")
i = 0
while 1:
os.system("clear")
print words[i]
time.sleep(1)
i += 1
i = i%len(words)
我希望能够在中间按“q”或“p”分别退出和暂停。
答案 0 :(得分:9)
Python标准库中的select模块可能是您正在寻找的 - 标准输入具有FD 0,但您可能还需要将终端设置为“原始”(而不是“熟”) )模式,在unix-y系统上,从它获得单个按键,而不是整行与行结束。如果在Windows上,msvcrt(也在Python标准库中)具有您需要的所有功能 - msvcrt.kbhit()
会告诉您是否有任何键击未决,如果是,msvcrt.getch()
会告诉您这是个性格。
答案 1 :(得分:3)
您还可以查看那里提供的one of the recipes,它为您提供了Unix和Windows所需的功能。
答案 2 :(得分:1)
你可以用线程做到这一点,这是一个基本的例子:
import threading, os, time, itertools, Queue
# setting a cross platform getch like function
# thks to the Python Cookbook
# why isn't standard on this battery included language ?
try : # on windows
from msvcrt import getch
except ImportError : # on unix like systems
import sys, tty, termios
def getch() :
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try :
tty.setraw(fd)
ch = sys.stdin.read(1)
finally :
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
# this will allow us to communicate between the two threads
# Queue is a FIFO list, the param is the size limit, 0 for infinite
commands = Queue.Queue(0)
# the thread reading the command from the user input
def control(commands) :
while 1 :
command = getch()
commands.put(command) # put the command in the queue so the other thread can read it
# don't forget to quit here as well, or you will have memory leaks
if command == "q" :
break
# your function displaying the words in an infinite loop
def display(commands):
string = "the fox jumped over the lazy dog"
words = string.split(" ")
pause = False
command = ""
# we create an infinite generator from you list
# much better than using indices
word_list = itertools.cycle(words)
# BTW, in Python itertools is your best friend
while 1 :
# parsing the command queue
try:
# false means "do not block the thread if the queue is empty"
# a second parameter can set a millisecond time out
command = commands.get(False)
except Queue.Empty, e:
command = ""
# behave according to the command
if command == "q" :
break
if command == "p" :
pause = True
if command == "r" :
pause = False
# if pause is set to off, then print the word
# your initial code, rewritten with a generator
if not pause :
os.system("clear")
print word_list.next() # getting the next item from the infinite generator
# wait anyway for a second, you can tweak that
time.sleep(1)
# then start the two threads
displayer = threading.Thread(None, # always to None since the ThreadGroup class is not implemented yet
display, # the function the thread will run
None, # doo, don't remember and too lazy to look in the doc
(commands,), # *args to pass to the function
{}) # **kwargs to pass to the function
controler = threading.Thread(None, control, None, (commands,), {})
if __name__ == "__main__" :
displayer.start()
controler.start()
像往常一样,使用线程很棘手,所以在编码之前一定要明白你做了什么。
警告:队列将在Python 3中重命名为队列。