PDA

View Full Version : [Python] Eseguire una funzione passata come parametro


xwang
13-02-2011, 12:33
Ciao a tutti,
vorrei sapere se è possibile eseguire una funzione passata come parametro.
Mi spiego meglio.
Chiamiamo A il "main" e ipotizziamo che tra i parametri da riga di comando ci sia il nome di una funzione da chiamare (ad es B) definita in un altro file.py.
Se il nome della funzione è il primo argomento argv[1], servirebbe qualcosa del tipo
chiama(argv[1])
E' possibile?
Grazie,
Xwang

PS spero che sia chiaro cosa mi servirebbe

xwang
13-02-2011, 13:14
Forse ho risolto usando il modulo runpy.run_module.
Va bene o ci ono alternative migliori?
Grazie,
Xwang

cdere
13-02-2011, 13:27
sì, scrivo di getto senza provare però, quindi potrebbe esserci qualche errore ma l'idea è quella.


lista_comandi = [e.lstrip('-') for e in sys.argv[1:]]
for comando in lista_comandi:
eval(comando)()

xwang
13-02-2011, 14:51
Con runpy funziona, ma non sono riuscito a condividere variabili globali tra le due funzioni (forse perchè ho solo qualche ora di esperienza con python...).
In serata proverò anche con eval, magari semplifica i problemi con le global.
Xwang

cdere
13-02-2011, 15:22
anche se non ti ho detto che l'utilizzo di eval è sconsigliato, dà non poche rogne dal punto di vista di manutenibilità del codice e altro.. puoi risolvere così:


lista_comandi = [e.lstrip('-') for e in sys.argv[1:]]
for comando in lista_comandi:
getattr(nomemodulo, comando, altrafunz_se_comando_nonsitrova)()


se invece 'comando' fa parte del modulo corrente o risolvi con sys.modules(__name__) al posto di nomemodulo o con globals().get(comando, altrafunz_se_comando_nonsitrova)

cdimauro
14-02-2011, 06:32
def g():
print 'g!'

def f():
print 'f'!

Dispatcher = {'f' : f, 'g' : g}

MiaFunzione = 'f'

Dispatcher[MiaFunzione]()
Oppure (ma più "oscura"):
def g():
print 'g!'

def f():
print 'f'!

MiaFunzione = 'f'

globals()[MiaFunzione]()

xwang
19-02-2011, 10:46
Ho risolto così:

module=__import__(moduleName)

importando il modulo e poi chiamando le singole funzioni del modulo importato (che saranno sempre le stesse al varaiare dei moduli).
Che ne pensate?
Xwang

xwang
21-02-2011, 22:53
Un'altra domanda. Meglio pyton 2.6.5 o 3.1.2? Ubuntu me li rende disponibili tutti e due, ma adesso è installata la 2.6.5.
Xwang

cdere
21-02-2011, 22:59
ad oggi, se devi imparare qualcosa e non hai vincoli di sorta (librerie particolari che non vanno ancora con python 3, vedi django o twisted) vai con python 3.
Che poi non capisco come ubuntu sia ferma al 2.6.x visto che l'ultima release stabile di ramo 2.x è la 2.7...

xwang
21-02-2011, 23:04
ad oggi, se devi imparare qualcosa e non hai vincoli di sorta (librerie particolari che non vanno ancora con python 3, vedi django o twisted) vai con python 3.
Che poi non capisco come ubuntu sia ferma al 2.6.x visto che l'ultima release stabile di ramo 2.x è la 2.7...

Beh io sto usando la 10.04 che aggiornerò alla prossima LTS che dovrebbe essere la 11.10 (mi sono stufato di aggiornare ogni 6 mesi).
Xwang

cdimauro
22-02-2011, 21:32
Ho risolto così:

module=__import__(moduleName)

importando il modulo e poi chiamando le singole funzioni del modulo importato (che saranno sempre le stesse al varaiare dei moduli).
Che ne pensate?
Xwang
Che è molto pulita come soluzione.

Riguardo alle versioni di Python, concordo con cdere.

xwang
22-02-2011, 23:27
Grazie ad entrambi per l'aiuto.
Mi sto appassionando sempre più a python e sto sperimentando un po' anche con shedskin nel caso mi servisse più velocità.
Ovviamente non mancherò di "rompervi" con altre domande :-)
Per la versione rimarrò su questa 2.6.5
Xwang

xwang
24-02-2011, 00:08
Eccomi qui.
Adesso le cose si fanno difficili.
Il programma A chiama all'interno di un ciclo infinito la funzione B.
E questo va bene.
Però avrei bisogno di usare un joystick e di inviare/ricevere pacchetti udp.
Per il joystick serve con pygame un ciclo infinito che rimanga in ascolto di eventi dal joystick e per la ricezione dei pacchetti UDP penso serva la stessa cosa.
Come faccio?
Temo di aver bisogno di usare dei thred specifici per i due listener del joystick e dei pacchetti UDP.
Sbaglio?
Grazie,
Xwang

cdimauro
24-02-2011, 12:58
Penso sia la strada corretta.

xwang
24-02-2011, 21:37
Penso sia la strada corretta.

Mi puoi consigliare esempi o dove trovare documentazione al riguardo?
Grazie,
Xwang

cdimauro
25-02-2011, 13:07
Per i thread?

xwang
25-02-2011, 18:12
Per i thread?

Si.
Anche perchè sinceramente gli esempi che ho visto svolgono tutti dei cicli while infiniti e non capisco come non facciano ad occupare la cpu al 100% senza fare niente.
Inoltre non ho capito come passare dati dal mio programma ai thread e viceversa.
Xwang

cdimauro
25-02-2011, 19:02
import Queue, threading, time

class CustomThread(threading.Thread):

def run(self):

while True:
Job = Jobs.get()
print 'Ho ricevuto il seguente lavoro:', Job
Results.put(Job)

Jobs = Queue.Queue()
Results = Queue.Queue()

MyThread = CustomThread()
MyThread.start()

Jobs.put('Uno!')
time.sleep(1)
Jobs.put('Due!')
time.sleep(1)
Jobs.put('Tre!')

while len(Results):
print 'Ho ricevuto:', Results.get()

xwang
25-02-2011, 20:58
Grazie,
adesso ci lavorerò per le comunicazioni udp.
Nel frattempo ho risolto il problema del joystick usando pygame, inizializzando il joystick e con una funzione che ad ogni chiamata processa tutti gli eventi in coda non ancora analizzati.
Fino ad uin rateo di 200 hz non ho problemi quindi posso fare a meno per il joystick (e per ciò che voglio fare) di un thread apposito.
Xwang