103 votes

Entrée au clavier avec délai d'attente?

Comment demanderiez-vous à l'utilisateur de saisir des données mais en arrêtant après N secondes ?

Google pointe vers un fil de discussion par e-mail à ce sujet sur http://mail.python.org/pipermail/python-list/2006-January/533215.html mais cela ne semble pas fonctionner. Peu importe la déclaration dans laquelle le délai d'attente se produit, que ce soit un sys.input.readline ou un timer.sleep(), j'obtiens toujours :

: [raw_]input expected at most 1 arguments, got 2

ce que sauf erreur ne parvient pas à capturer.

3voto

iperov Points 26

Ma solution multiplateforme

def input_process(stdin_fd, sq, str):
    sys.stdin = os.fdopen(stdin_fd)
    try:
        inp = input (str)
        sq.put (True)
    except:
        sq.put (False)

def input_in_time (str, max_time_sec):
    sq = multiprocessing.Queue()
    p = multiprocessing.Process(target=input_process, args=( sys.stdin.fileno(), sq, str))
    p.start()
    t = time.time()
    inp = False
    while True:
        if not sq.empty():
            inp = sq.get()
            break
        if time.time() - t > max_time_sec:
            break
    p.terminate()
    sys.stdin = os.fdopen( sys.stdin.fileno() )
    return inp

3voto

Chiebukar Points 43

Cela fait déjà des années, mais au cas où quelqu'un tomberait dessus comme je l'ai fait récemment en essayant de résoudre ce genre de problème, il existe un moyen facile et plus rapide d'y parvenir en utilisant le func-timeout package. Il doit être installé avant utilisation pour la plupart des IDEs; vous pouvez l'installer via pip. Le lien ci-dessus est explicite, mais je donnerai un exemple de comment je l'ai implémenté.

from func_timeout import FunctionTimedOut, func_timeout

try:
   ans = func_timeout(5, lambda: int(input('Quelle est la somme de 2 et 3?\n')))
   print(ans)
except FunctionTimedOut:
   print(5)

func_timeout renvoie la valeur de la méthode dans son argument, la fonction question() dans ce cas. Il permet également d'autres arguments nécessaires pour la fonction (voir la documentation). Si le temps défini s'écoule (5 secondes ici), il déclenche une TimedOutException et exécute le code dans le bloc except.

3voto

Treece Points 31
from threading import Thread
import time

def get_input():
    while True:
        print(input('> '))

t1 = Thread(target=get_input)
t1.setDaemon(True)
t1.start()
time.sleep(3)
print('program exceeds')

Eh bien il suffit simplement de définir un nouveau thread démon, et de définir un temps d'attente de votre choix pour le timeout. Je pense que c'est facile à rattraper XD

2voto

Analogue à Locane pour les fenêtres:

import subprocess  
subprocess.call('timeout /T 30')

2voto

kkonrad Points 56

Réponse modifiée d'iperov qui fonctionne pour moi (python3 win10 2019-12-09)

changements à iperov:

  • remplacer str par sstr car str est une fonction en python

  • ajouter des imports

  • ajouter un sleep pour réduire l'utilisation du processeur de la boucle while (?)

  • ajouter si name\=='main': # requis par multiprocessing sur windows

    import sys, os, multiprocessing, time

    def processus_input(stdin_fd, sq, sstr):
        sys.stdin = os.fdopen(stdin_fd)
        try:
            inp = input(sstr)
            sq.put(True)
        except:
            sq.put(False)
    
    def entrée_à_temps(sstr, max_time_sec):
        sq = multiprocessing.Queue()
        p = multiprocessing.Process(target=processus_input, args=( sys.stdin.fileno(), sq, sstr))
        p.start()
        t = time.time()
        inp = False
        while True:
    
            if not sq.empty():
                inp = sq.get()
                break
            if time.time() - t > max_time_sec:
                break
    
            tleft=int( (t+max_time_sec)-time.time())
            if tleft0:
                print('\n  ...temps restant '+str(tleft)+'s\ncommande:')
    
            time.sleep(2)
    
        p.terminate()
        sys.stdin = os.fdopen( sys.stdin.fileno() )
        return inp
    
    if __name__=='__main__':
        entrée_à_temps("commande:", 17)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X