【问题标题】:Python: Repeating a function until a keypress is initiatedPython:重复一个功能,直到启动按键
【发布时间】:2016-05-07 22:25:27
【问题描述】:

我的函数“hello()”只是在屏幕上显示一个刺激 2 秒,在此期间可以按下一个键。如果没有按下某个键,它会等待 1 秒,然后再次运行该函数,如果没有按下任何键,则一遍又一遍地运行。当一个键被按下时,它退出while循环并打印yes。出于某种原因,如果我让函数循环,例如,在我按下一个键之前循环 4 次,我会同时得到 5 个打印状态,而我只期望一个。有人能告诉我为什么它似乎在存储打印语句,尽管我希望在我按下一个键之前永远不会到达打印语句?

def hello():
    test = 1 
    running = 1
    while running == 1:
        for frame in range(short_frames):      # 2 seconds
            fix.draw()
            window.flip()

            allKeys = event.getKeys(keyList = ('g','h'))
            for thisKey in allKeys:
                if thisKey == 'g':
                    keyTime=core.getTime()
                    test = 2
                elif thisKey == 'h':
                    keyTime=core.getTime()
                    test = 2

        window.flip()
        core.wait(1)

        if test == 1:               #if no key is pressed
            hello()                 #run the function again

        running = 2                 #exit out of while loop

    print "yes"

for i in range(1):
    hello()
core.quit()
window.close()

【问题讨论】:

    标签: python psychopy


    【解决方案1】:

    您在hello 中调用了函数hello。这是递归。到第 5 次,您按下一个键。它将打印您的 thing 并结束 hello 的第 5 次调用。您的程序返回到第 4 个hello 并捕获按下的键。函数hello 的第4 次调用将再次打印,结束第4 次hello 并返回hello 的第3 次调用等等......

    您应该小心 recursion。 我不知道,为什么你需要变量testrunning。但是这些代码会起作用。

    def hello():
        is_pressed = False
        while not is_pressed:
            for frame in range(short_frames):      # 2 seconds
                fix.draw()
                window.flip()
    
                allKeys = event.getKeys(keyList = ('g','h'))
                for thisKey in allKeys:
                    if thisKey == in ['g', 'h']
                        keyTime=core.getTime()
                        is_pressed = True
    
            window.flip()
            core.wait(1)
    
        print "yes"
    

    【讨论】:

    • 谢谢。虽然这会保持 while 循环直到按下一个键,但如果没有按下任何键,我需要再次运行整个函数,而不仅仅是 while 循环。这就是我在 hello() 中再次调用 hello() 的原因,我认为它会立即跳回到函数的开头而不打印。
    • 虽然我同意所有反对递归的警告,并且我认为您可以更简单地做您想做的事,但可以使用以下内容测试是否没有按键:keys = event.waitKeys(maxWait = 1800, keyList = keyList); if isinstance(keys, types.NoneType) or keys[0] == 'escape': quit(); where NoneType 用于这些行,以查看是否退出我们的某个程序的一部分。
    【解决方案2】:

    hello() 递归调用自身。每次调用它都会打印一次输出。为了得到你想要的效果,你需要这样的东西:

    def hello():
        test = 1 
        running = 1
        while running == 1:
            for frame in range(short_frames):      # 2 seconds
                fix.draw()
                window.flip()
    
                allKeys = event.getKeys(keyList = ('g','h'))
                for thisKey in allKeys:
                    if thisKey == 'g':
                        keyTime=core.getTime()
                        test = 2
                    elif thisKey == 'h':
                        keyTime=core.getTime()
                        test = 2
    
            window.flip()
            core.wait(1)
            running = test
    
        print "yes"
    
    for i in range(1):
        hello()
    core.quit()
    window.close()
    

    在 while 循环的底部,如果 test 没有改变(即没有按下某个键),running 将被设置为 1 并且循环将继续。如果 test 为 2(按下了一个键),running 将设置为 2 并且循环将退出。 "yes" 字符串只会打印一次,因为 hello() 只被调用一次。

    更新:

    def hello():
        test = 1 
        for frame in range(short_frames):      # 2 seconds
            fix.draw()
            window.flip()
    
            allKeys = event.getKeys(keyList = ('g','h'))
            for thisKey in allKeys:
                if thisKey == 'g':
                    keyTime=core.getTime()
                    test = 2
                elif thisKey == 'h':
                    keyTime=core.getTime()
                    test = 2
    
            window.flip()
            core.wait(1)
            return test
    
    running = 1
    while running == 1:
        running = hello()
    print "yes"
    core.quit()
    window.close()
    

    【讨论】:

    • 谢谢。虽然这会保持 while 循环直到按下一个键,但如果没有按下任何键,我需要再次运行整个函数,而不仅仅是 while 循环。这就是我在 hello() 中再次调用 hello() 的原因,我认为它会立即跳回到函数的开头而不打印。
    • 在我的回答中查看更新。将 while 循环移到函数之外很容易,这样每次迭代都会调用函数。如果你关心的是“pythonic”,那么在测试和运行中使用 True 和 False 会更好(而不是 1 和 2)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多