On Sun, Mar 08 2015, Alessandro Re wrote: > Ciao lista, > > ho un problema con delle callback, e sapendo che ci sono sistemi in > cui si usano molto (e.g. in ambito web), magari qualcuno di voi mi può > illuminare (scusate, il post è un po' lungo). > > Ho degli oggetti python che fanno riferimento a degli oggetti C++, > quindi a volte mi trovo nella situazione in cui un oggetto C++ viene > distrutto e, se l'oggetto python esiste ancora e cerca di far > riferimento ad esso, provoca - giustamente - errore. > > Ora, dal lato python ho delle callback per gestire degli eventi che > arrivano da C++: quando un certo evento accade, una funzione python > viene chiamata. > > Quindi immaginate di avere un oggetto A che emette un evento E, ed un > oggetto B che ha una callback C associata ad E: quando E accade, C > viene chiamata. > > Il problema è questo: può capitare che un metodo remove() di B venga > chiamato, provocando la rimozione dell'oggetto C++ sottostante; ma non > dell'oggetto python B, perché la sua callback è ancora registrata. Se > per caso in C venisse usato l'oggetto C++, si alzerebbe una bella > eccezione. > > Ora, la mia domanda è: come posso costruire in python un sistema in > cui io posso attaccare due oggetti, ma quando un certo metodo (e.g. > remove) viene chiamato, allora tutte le callback registrate vengono > rimosse senza troppo sforzo e tutti gli oggetti garbage-collected come > ci si aspetterebbe?
C == oggetto in c++ con riferimento all'oggetto python P == oggetto python Come registri le callback? Gli oggetti in python sono referenziati da del codice python o solo dalle callback di c++? In questo caso basta che, nel momento in cui distruggi l'oggetto C, deregistri le callback e riduci il numero di referenze del metodo. Se i metodi di un oggetto P sono usati come callback di un solo oggetto C, al momento che tu rilasci tutte le callback non esistono più riferimenti all'oggetto python. Se al momento della distruzione dell'oggetto C vuoi chiamare un'ultima callback, chiama la callback e poi rimuovi il riferimento alla stessa. > Conoscete dei pattern, degli idiomi, o qualunque cosa per poter > implementare questo? > > Ho poi una seconda domanda, che fortunatamente richiede meno parole :) > > A volte, viene dato un certo comando, ad esempio "send_data(123)"; > questa operazione viene fatta in modo asincrono, cioé il controllo > torna subito all'utente e una callback verrà chiamata quando > l'operazione è stata completata. > > Come posso rendere sincrona (bloccante) l'invocazione di un comando? > > Un modo tanto semplice quanto barbaro è il seguente: > > free_to_go = False > def on_packet_sent(): > global free_to_go > free_to_go = True > > def send_data_blocking(data): > global free_to_go > free_to_go = False > send_data(data, callback=on_packet_sent) > while not free_to_go: > pass > > send_data_blocking(123) La prima idea che mi viene in mente è di infilare la callback dentro la send e di chiamare sleep per salvare qualche ciclo macchina: def send_data_blocking(data): def go(): free_to_go = True free_to_go = False send_data(data, callback=go) while not free_to_go: sleep(0.1) abbastanza naïve ma non dai tante informazioni a proposito e quindi per esempio nessuna gestione degli errori. send_data a parte il codice è thread-safe. ciao m. _______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python