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.

124voto

Pontus Points 521

Utiliser un appel select est plus court, et devrait être beaucoup plus portable

import sys, select

print "Vous avez dix secondes pour répondre!"

i, o, e = select.select( [sys.stdin], [], [], 10 )

if (i):
  print "Vous avez dit", sys.stdin.readline().strip()
else:
  print "Vous n'avez rien dit!"

51voto

user137673 Points 867

L'exemple auquel vous avez lié est incorrect et l'exception se produit en réalité lors de l'appel du gestionnaire d'alarme au lieu de lorsque la lecture est bloquée. Essayez plutôt ceci:

import signal
TIMEOUT = 5 # nombre de secondes que vous souhaitez pour le délai

def interrupted(signum, frame):
    "appelé lorsque la lecture dépasse le délai"
    print 'interrompu!'
signal.signal(signal.SIGALRM, interrupted)

def input():
    try:
            print 'Vous avez 5 secondes pour taper vos éléments...'
            foo = raw_input()
            return foo
    except:
            # temps écoulé
            return

# définir l'alarme
signal.alarm(TIMEOUT)
s = input()
# désactiver l'alarme après le succès
signal.alarm(0)
print 'Vous avez tapé', s

20voto

by j Points 111

Si vous ne vous souciez pas de comment cela fonctionne, il vous suffit de
pip install inputimeout
et

from inputimeout import inputimeout, TimeoutOccurred

if __name__ == "__main__":
    try:
        c = inputimeout(prompt='hello\n', timeout=3)
    except TimeoutOccurred:
        c = 'timeout'
    print(c)

si facile
https://pypi.org/project/inputimeout/

17voto

Locane Points 1487

Pas une solution Python, mais...

J'ai rencontré ce problème avec un script tournant sous CentOS (Linux), et ce qui a fonctionné pour ma situation était simplement d'exécuter la commande Bash "read -t" dans un processus fils. Une solution brutale et dégoûtante, je sais, mais je me sens suffisamment coupable de l'efficacité avec laquelle cela a fonctionné que je voulais le partager avec tout le monde ici.

import subprocess
subprocess.call('read -t 30', shell=True)

Tout ce dont j'avais besoin était quelque chose qui attendait 30 secondes à moins que la touche ENTER ne soit pressée. Cela a très bien fonctionné.

13voto

Paul Points 69

Et voici un qui fonctionne sur Windows

Je n'ai pas réussi à faire fonctionner aucun de ces exemples sur Windows, alors j'ai fusionné quelques réponses différentes de StackOverflow pour obtenir ce qui suit:

import threading, msvcrt
import sys

def readInput(caption, default, timeout = 5):
    class KeyboardThread(threading.Thread):
        def run(self):
            self.timedout = False
            self.input = ''
            while True:
                if msvcrt.kbhit():
                    chr = msvcrt.getche()
                    if ord(chr) == 13:
                        break
                    elif ord(chr) >= 32:
                        self.input += chr
                if len(self.input) == 0 and self.timedout:
                    break    

    sys.stdout.write('%s(%s):'%(caption, default));
    result = default
    it = KeyboardThread()
    it.start()
    it.join(timeout)
    it.timedout = True
    if len(it.input) > 0:
        # wait for rest of input
        it.join()
        result = it.input
    print ''  # needed to move to next line
    return result

# et quelques exemples d'utilisation
ans = readInput('Veuillez taper un prénom', 'john') 
print 'Le prénom est %s' % ans
ans = readInput('Veuillez entrer un nombre', 10 ) 
print 'Le nombre est %s' % ans

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