【问题标题】:exit while loop with user prompt in python在python中使用用户提示退出while循环
【发布时间】:2013-07-31 23:28:57
【问题描述】:

我已经浏览了很长时间来寻找这个问题的答案。

我在 Unix 中使用 Python 2.7。

我有一个连续的while循环,我需要一个选项,用户可以中断它,做一些事情,然后循环将继续。

喜欢:

while 2 > 1:
     for items in hello:
         if "world" in items:
             print "hello"
         else:
             print "world"

      time.sleep(5)
      here user could interrupt the loop with pressing "u" etc. and modify elements inside he loop. 

我开始使用 raw_input 进行测试,但由于它会在每个周期都提示我,所以我不需要它。

我试过这里提到的方法:

Keyboard input with timeout in Python

几次,但似乎都没有按照我的意愿工作。

【问题讨论】:

  • 您希望它如何工作?我想那时只有一个词适合你:线程。
  • 为什么要使用while 2>1 而不是while True
  • raw_input() 无法读取一个字符,因为“普通”控制台输入是行缓冲的。请参阅此无缓冲阅读配方code.activestate.com/recipes/134892
  • 我在原始代码中使用了 True。感谢您提及线程。我会调查这些。
  • 信号方法(在您链接到的问题中讨论过)对您不起作用怎么办?看来这应该是一个可行的解决方案...否则,您可以尝试使用 select (docs.python.org/release/2.5.2/lib/module-select.html) 来轮询键盘,看看它是否有任何新的输入。

标签: python


【解决方案1】:
>>> try:
...    print 'Ctrl-C to end'
...    while(True):
...       pass
... except KeyboardInterrupt, e:
...    print 'Stopped'
...    raise
...
Ctrl-C to end
Stopped
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt
>>>

显然,您需要将 pass 替换为您正在做的任何事情,然后打印出来。

【讨论】:

    【解决方案2】:

    以下是通过轮询标准输入的方法:

    import select, sys
    p = select.poll()
    p.register(sys.stdin, 1) #select the file descriptor, 
                #in this case stdin, which you want the 
                #poll object to pay attention to. The 1 is a bit-mask 
                #indicating that we only care about the POLLIN 
                #event, which indicates that input has occurred
    
    while True:
         for items in hello:
             if "world" in items:
                  print "hello"
             else:
                  print "world"
    
         result = p.poll(5) #this handles the timeout too
         if len(result) > 0: #see if anything happened
             read_input = sys.stdin.read(1)
             while len(read_input) > 0:
                  if read_input == "u":
                      #do stuff!
                  read_input = sys.stdin.read(1) #keep going 
                                #until you've read all input
    

    注意:这可能不适用于 Windows。

    【讨论】:

      【解决方案3】:

      你可以做嵌套的while循环,结构如下:

      while true:
          go = True
          while go:
           for items in hello:
               if "u" in items:
                   go = False
               else if "world" in items:
                   print "hello"
               else:
                   print "world"
          #Here you parse input to modify things in the nested loop, include a condition to set       
          #go back to true to reenter the loop                     
      

      【讨论】:

      • Python 是一种区分大小写的语言。 “真”和“假”没有定义。它们应该是“真”和“假”。
      • 这会遍历“hello”并从那里搜索“u”,这不是问题。
      • 我知道它的作用。我认为你好是他的输入列表,尽管没有太多文档。我虽然您的问题是在输入命令时退出循环,然后再重新输入,这概述了(尽我所能,不了解您的任何变量的作用)如何做。
      【解决方案4】:
      import sys
      import os
      import time
      
      import termios
      import tty
      import fcntl
      import errno
      
      KEY = "u"
      
      def read_characters(f):
          fd = f.fileno()
      
          # put descriptor in non-blocking mode
          flags = fcntl.fcntl(fd, fcntl.F_GETFL)
          fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
      
          try:
              while 1:
                  try:
                      yield f.read(1)
                  except IOError as e:
                      if e.errno == errno.EAGAIN:
                          # no more characters to read
                          # right now
                          break
          finally:
              # restore blocking mode
              fcntl.fcntl(fd, fcntl.F_SETFL, flags)
      
      def main():
          fd = sys.stdin.fileno()
      
          # save current termios settings
          old_settings = termios.tcgetattr(fd)
      
          # tty sets raw mode using termios module
          tty.setraw(fd)
      
          try:
              while True:
                  time.sleep(1)
      
                  for c in read_characters(sys.stdin):
                      if c == KEY: break
                  else:
                      c = None
      
                  if c == KEY: break
      
                  sys.stdout.write("still going\r\n")
      
          finally:
              # restore terminal settings
              termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
      
      if __name__ == "__main__":
          main()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-15
        • 2022-07-12
        • 1970-01-01
        • 2015-08-15
        • 1970-01-01
        • 2011-11-07
        • 2016-08-13
        • 1970-01-01
        相关资源
        最近更新 更多