【问题标题】:Timeout or User Input to Repeat in Python Loops在 Python 循环中重复的超时或用户输入
【发布时间】:2017-06-11 04:24:19
【问题描述】:

在我在 Windows 7 Professional 64 上运行的以下程序中,我试图允许用户在需要时进行干预(通过内部 while 循环)并导致外部 while 循环重复操作.否则,内部 while 循环将超时,程序将继续畅通无阻:

import msvcrt
import time

decision = 'do not repeat' # default setting

for f in ['f1', 'f2', 'f3']:

    print ('doing some prepartory actions on f')

    while True: # outer while loop to allow repeating actions on f

        print ('doing some more actions on f')

        t0 = time.time()
        while time.time() - t0 < 10:        # inner while loop to allow user to intervene 
            if msvcrt.kbhit():              # and repeat actions by pressing ENTER if
                if msvcrt.getch() == '\r':  # needed or allow timeout continuation
                    decision = "repeat"
                    break
                else:
                    break
            time.sleep(0.1)

        if decision == "repeat":
            print ("Repeating f in the outer while loop...")
            continue

        else:
            break

    print ('doing final actions on f in the for loop')

但是,内部循环的用户输入部分(按 ENTER 重复)不起作用,我不知道为什么。我从here 提供的解决方案中获得了它的想法。 关于如何让它发挥作用的任何想法?

【问题讨论】:

  • kbhitgetch 要求将进程附加到控制台窗口。如果您使用的是 IDLE,则该进程没有控制台——至少在使用 pythonw.exe 以默认方式运行时没有。即使您确实使用附加的控制台运行 IDLE(例如,使用 Win+R 运行对话框来运行 py -3 -m idlelib),我怀疑您是否希望用户必须切换到控制台窗口才能输入输入。
  • 反正IDLE等IDE shell只是开发环境。如果您打算将其用作控制台脚本,则可以模拟假控制台 I/O 函数,以便在没有附加控制台时用于测试(例如,open("CONIN$") 失败)。如果它不应该是控制台程序,那么使用 GUI 工具包创建您自己的窗口并读取键盘输入。

标签: python windows loops timeout controls


【解决方案1】:

由于您使用的是 == 运算符,因此您在内部循环中比较变量决策和字符串“重复”。您应该使用 = 来为变量赋值:

decision = 'repeat'

【讨论】:

  • 感谢您注意到这一点。我修复了它,但它与内循环无关。我还将for 循环集更改为字符串以允许代码运行。
  • 你确定msvcrt.getch()返回'\r'吗?
  • 这似乎是您在 Windows 上按 ENTER 时预期返回的内容。这就是我借来的代码。
  • 可能是时间问题,因为其他一切看起来都不错。尝试在内部循环中一一调试您的代码步进线。我不在电脑上,所以现在无法测试。
  • 谢谢。我进行了逐步调试。即使按下键,msvcrt.kbhit() 也不会返回 True
【解决方案2】:

我现在已经设法解决了这个问题。 kbhit 进程在我使用的 IDLE(Wing IDE)中不起作用,但如果从命令提示符调用(这可能适用于所有 IDLE,而不仅仅是 Wing,正如 @eryksun 所说)。我发现的另一个问题是getch() 进程不能满足我的需要,我必须使用返回 unicode 的getwch()。再做一次小的调整(默认decisiondecision = 'Reset decision to not repeat',代码现在处于良好的工作状态:

import msvcrt
import time

decision = 'do not repeat' # default setting

for f in ['f1', 'f2', 'f3']:

    print ('doing some prepartory actions on f')

    while True: # outer while loop to allow repeating actions on f

        print ('doing some more actions on f')

        t0 = time.time()
        while time.time() - t0 < 10:        # inner while loop to allow user to intervene 
            if msvcrt.kbhit():              # and repeat actions by pressing ENTER if
                if msvcrt.getchw() == '\r': # needed or allow timeout continuation
                    decision = "repeat"
                    break
                else:
                    break
            time.sleep(0.5)

        if decision == "repeat":
            print ("Repeating f in the outer while loop...")
            decision = 'Reset decision to not repeat'
            continue

        else:
            break

    print ('doing final actions on f in the for loop')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-29
    • 1970-01-01
    • 2019-09-26
    相关资源
    最近更新 更多