[Python] Gestire eventi con callback

Alessandro Re ale a ale-re.net
Dom 8 Mar 2015 21:04:25 CET


Ciao Manlio,

> Cosa usi per interfacciarti con codice C++?
> Che errore ottieni?

Come dicevo a flandero, non ho controllo sulla parte C++, non so cosa
venga usato per l'interfaccia e in questo caso lavoro 100% python.
Ottengo un errore tipo "L'oggetto C++ è già stato distrutto", quando
cerco di fare riferimento ad esso dopo aver chiamato la remove().

Ho però realizzato che il mio problema di fondo è nella gestione delle
callback costruite "al volo": purtroppo con python mi è troppo facile
lavorare in modo semi-funzionale, e quando devo collegare tra loro due
eventi, non è quasi mai un lavoro pulito. Ad esempio:

pr = Producer()
co = Consumer()
pr.register('on_data_ready', co.print_data)

In questo caso, tutto è molto lineare: un oggetto stampa i dati che
l'altro fornisce. Se co venisse distrutto, chiaramente un eventi
data_ready sarebbe problematico, a meno che non si è fatto
unregister() prima della distruzione.

Ora, finché la registrazione e de-registrazione coinvolgono due
oggetti, non ci metto molto a trovare una strategia per tenere le cose
pulite.

Il problema sorge se invece faccio così:

def clean_and_print(data):
    data.replace(" ", " ")
    co.print_data(data)

pr.register('on_data_ready', clean_and_print)

In questo caso, mi esce più difficile immaginare un meccanismo che,
quando co viene rimosso, allora la funzione clean_and_print - che usa
co - venga de-registrata.

Il motivo è che mentre riesco a concepire facilmente un sistema per
cui degli oggetti implementano un'interfaccia standard che gestisca le
callback e la loro rimozione sicura all'atto di distruzione, non mi
esce così facile fare lo stesso per delle funzioni normali. Magari si
potrebbe usare un decoratore, ma così su due piedi non mi si accende
alcuna lampadina.

Avete delle idee o dei commenti a riguardo? Magari sto semplicemente
sbagliando approccio.

> Non so se è un uso corretto, ma puoi provare ad usare una weakref, oppure
> qualcosa di simile personalizzato.

Ok, darò un occhio anche a questo, non ci avevo pensato.

>> Quindi immaginate ...
>> [...]
>
> Troppo complesso, passo.

lol

>> Come posso rendere sincrona (bloccante) l'invocazione di un comando?
>>
> https://gist.github.com/perillo/21234cf7b06873227cb2

Molto interessante, grazie!!
~Ale


Maggiori informazioni sulla lista Python