2 | ||
Editor: pycz
Time: 2011/10/15 12:15:20 GMT+2 |
||
Note: pridavani znacek 2x-3x |
changed: - .. image:: py30.png :align: right Dočasné čekání na vstup ======================== *Vytaženo a upraveno z konference* Dotaz ----- Ahoj, potřebuji aby když uživatel neodpoví na výzvu *input()* do 5 sekund, aby čekání na odpověď skončilo a dosadila se nějaké defaultní hodnota. Obecná odpověď ----------------- Zdravím, Nejjednodušší (a nejelegantnější) by bylo použití funkce alarm a obsluhy SIGALRM, ale to je možné pouze na rozumných OS, které vyhovují normě POSIX (což by správně měly všechny systémy, ale nic není ideální...). Další možností by bylo použití funkce select, ale to také na OS, který nejmenujeme, nepůjde (tam funguje select jen se sockety). Možná by šlo určitým způsobem využít nonblocking IO, ale to by nejspíš vyžadovalo pywin32 knihovny a nevím, jaká je úroveň podpory této funkce v technicky nedokonalých systémech. Řešení přes thready mi přijde docela komplikované a nespolehlivé, hlavně je otázkou přerušení raw_input funkce (možná by šlo použít něco jako externí interrupt vlákna, ale taktéž nevím, do jaké míry je tato funkce spolehlivá). Takže odpověď není jednoznačná, můžete vyzkoušet různé postupy, v případě zájmu o podrobnosti se ozvěte. GUI ---- Ne, nepotrebujes input(), potrebujes od uzivatele nejak *zadat hodnotu*. Tohle upresneni je pomerne zasadni :). Preruseni input() muze byt IMHO totiz pomerne problematicke. Na Tvem miste bych zkusil pouzit nejaky toolkit pro vytvareni TUI (textovych user interface), treba (n)curses nebo slang nebo GUI (Tkinter, PyGTK, ...). Windows -------- Není bez chyby, není takový jaký by měl, ale alespon neco. Jakmile napíšeš jediné písmeno, už není možno ukončit vlákno po zadané době. Problém totiž je, že nejde násilně ukončit vlákno, které čeká na obyčejném *input()* :: import threading, queue, time import msvcrt # Jen pro MS Windows vystup = queue.Queue() zamek = threading.Lock() def vlakno1(): time.sleep(5) vystup.put('konec') def vlakno2(): print ("Ocekavam vstup: ") while nasloucham.isAlive(): if msvcrt.kbhit(): zamek.acquire() vystup.put(input()) zamek.release() nasloucham = threading.Thread(target = vlakno1) cekamvstup = threading.Thread(target = vlakno2) nasloucham.start() cekamvstup.start() while nasloucham.isAlive() or not vystup.empty(): if not zamek.locked() and not vystup.empty(): print (vystup.get() ) Linux ------ Zaprvé píšu s křížkem po funuse a zadruhé tohle řešení bude fungovat jen na Operačních systémech, což už poznamenal regnarG. Takže si toho nevšímejte :-) :: #!/usr/bin/python import sys, select r = select.select([sys.stdin], [], [], 5) if r[0]: choice = sys.stdin.readline() else: choice = 'default\n' print 'Tvoje volba:', choice
Vytaženo a upraveno z konference
Ahoj, potřebuji aby když uživatel neodpoví na výzvu input() do 5 sekund, aby čekání na odpověď skončilo a dosadila se nějaké defaultní hodnota.
Zdravím, Nejjednodušší (a nejelegantnější) by bylo použití funkce alarm a obsluhy SIGALRM, ale to je možné pouze na rozumných OS, které vyhovují normě POSIX (což by správně měly všechny systémy, ale nic není ideální...). Další možností by bylo použití funkce select, ale to také na OS, který nejmenujeme, nepůjde (tam funguje select jen se sockety). Možná by šlo určitým způsobem využít nonblocking IO, ale to by nejspíš vyžadovalo pywin32 knihovny a nevím, jaká je úroveň podpory této funkce v technicky nedokonalých systémech. Řešení přes thready mi přijde docela komplikované a nespolehlivé, hlavně je otázkou přerušení raw_input funkce (možná by šlo použít něco jako externí interrupt vlákna, ale taktéž nevím, do jaké míry je tato funkce spolehlivá). Takže odpověď není jednoznačná, můžete vyzkoušet různé postupy, v případě zájmu o podrobnosti se ozvěte.
Ne, nepotrebujes input(), potrebujes od uzivatele nejak zadat hodnotu. Tohle upresneni je pomerne zasadni :). Preruseni input() muze byt IMHO totiz pomerne problematicke. Na Tvem miste bych zkusil pouzit nejaky toolkit pro vytvareni TUI (textovych user interface), treba (n)curses nebo slang nebo GUI (Tkinter, PyGTK, ...).
Není bez chyby, není takový jaký by měl, ale alespon neco. Jakmile napíšeš jediné písmeno, už není možno ukončit vlákno po zadané době. Problém totiž je, že nejde násilně ukončit vlákno, které čeká na obyčejném input()
import threading, queue, time import msvcrt # Jen pro MS Windows vystup = queue.Queue() zamek = threading.Lock() def vlakno1(): time.sleep(5) vystup.put('konec') def vlakno2(): print ("Ocekavam vstup: ") while nasloucham.isAlive(): if msvcrt.kbhit(): zamek.acquire() vystup.put(input()) zamek.release() nasloucham = threading.Thread(target = vlakno1) cekamvstup = threading.Thread(target = vlakno2) nasloucham.start() cekamvstup.start() while nasloucham.isAlive() or not vystup.empty(): if not zamek.locked() and not vystup.empty(): print (vystup.get() )
Zaprvé píšu s křížkem po funuse a zadruhé tohle řešení bude fungovat jen na Operačních systémech, což už poznamenal regnarG. Takže si toho nevšímejte :-)
#!/usr/bin/python import sys, select r = select.select([sys.stdin], [], [], 5) if r[0]: choice = sys.stdin.readline() else: choice = 'default\n' print 'Tvoje volba:', choice