2010-05-07 9 views
15

Devo aspettare in uno script fino a quando un certo numero di condizioni diventa vero?C'è un modo semplice in Python di aspettare fino a quando certe condizioni sono vere?

So che posso eseguire il rollover del mio evento utilizzando variabili di condizione e amici, ma non voglio passare attraverso tutti i problemi di implementazione, dal momento che alcune modifiche alle proprietà dell'oggetto provengono da thread esterni in una libreria C++ incapsulata (Boost .Python), quindi non posso semplicemente dirottare __setattr__ in una classe e inserire lì una variabile di condizione, che mi lascia o cercando di creare e segnalare una variabile di condizione Python da C++, o di avvolgere una variabile nativa e attendere su di essa in Python , entrambi i suoni sono complessi, inutilmente complicati e noiosi.

C'è un modo più semplice per farlo, escludendo il polling continuo della condizione?

Idealmente sarebbe lungo le linee di

res = wait_until(lambda: some_predicate, timeout) 
if (not res): 
    print 'timed out' 

risposta

16

Purtroppo l'unica possibilità di incontrare i vostri vincoli è di periodicamente sondaggio, per esempio ....:

import time 

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs): 
    mustend = time.time() + timeout 
    while time.time() < mustend: 
    if somepredicate(*args, **kwargs): return True 
    time.sleep(period) 
    return False 

o simili. Questo può essere ottimizzato in diversi modi se somepredicate può essere scomposto (ad esempio se è noto che è uno and di diverse clausole, specialmente se alcune delle clausole sono a loro volta soggette all'ottimizzazione essendo rilevabili tramite threading.Event s o qualsiasi altra cosa, ecc. Ecc.) , ma nei termini generali che chiedi, questo approccio inefficiente è l'unica via d'uscita.

+0

Questo è quello che ho finito per fare. Fortunatamente, le prestazioni non sono un problema (è uno script di prova). –

+0

potrebbe esserci un'altra soluzione http://stackoverflow.com/a/7836454/995714 –

2

Hai praticamente risposto alla tua domanda: no.

Dato che si tratta di librerie esterne in boost.python, che possono cambiare oggetti a loro piacimento, è necessario che queste routine richiamino un aggiornamento del gestore di eventi o lavorino con una condizione.

0

Ecco la filettatura estensione alla soluzione di Alex:

import time 
import threading 

# based on https://stackoverflow.com/a/2785908/1056345                                                                   
def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs): 
    must_end = time.time() + timeout 
    while time.time() < must_end: 
     if somepredicate(*args, **kwargs): 
      return True 
     time.sleep(period) 
    return False 

def wait_until_par(*args, **kwargs): 
    t = threading.Thread(target=wait_until, args=args, kwargs=kwargs) 
    t.start() 
    print ('wait_until_par exits, thread runs in background') 

def test(): 
    print('test') 

wait_until_par(test, 5) 
Problemi correlati