2010-11-09 16 views
16

Alcuni giorni fa stavo cercando in rete e ho trovato un interessante articolo sui dizionari Python. Si trattava di usare le chiavi nel dizionario per chiamare una funzione. In quell'articolo l'autore ha definito alcune funzioni e quindi un dizionario con la chiave esattamente uguale al nome della funzione. Poi ha potuto ottenere un parametro di input dall'utente e chiamare lo stesso metodo (qualcosa come implementare un'interruzione di caso) Successivamente ho realizzato la stessa cosa ma in qualche modo diverso. Voglio sapere come posso implementarlo. Se ho una funzione:Utilizzare una stringa per chiamare la funzione in Python

def fullName(name = "noName", family = "noFamily"): 
    return name += family 

E ora se ho una stringa come questa:

myString = "fullName(name = 'Joe', family = 'Brand')" 

C'è un modo per eseguire questa query e ottenere un risultato: JoeBrand
Per esempio qualcosa Ricordo che potremmo dare una stringa alla dichiarazione exec() e lo fa per noi. Ma non sono sicuro di questo caso speciale, e anche io non conosco il modo efficiente in Python. E inoltre sarò così grato di aiutarmi a gestire il valore restituito da tali funzioni, ad esempio nel mio caso, come posso stampare il nome completo restituito da tale funzione?

+2

si funzione è gonna ritorno Nessuno ... utilizzo + al posto di + = – Ant

+1

Per fare questo, l'uso: getattr (myString, 'fullName') (name = 'Joe', family = 'Brand') [vedi domanda duplicata collegata in cima alla pagina] – Stew

+0

[Nota: getattr() viene utilizzato dalla risposta superiore alla domanda che questo post duplica, ma non è menzionato di seguito. Ho pensato che sarebbe stato utile apparire su questa pagina stessa, quindi sto piegando la convenzione contro la risposta alle domande nei commenti.] – Stew

risposta

26

Si potrebbe utilizzare eval():

myString = "fullName(name = 'Joe', family = 'Brand')" 
result = eval(myString) 

Attenzione però, eval() è considerato male da molte persone.

+0

Grazie in anticipo, ma restituisce alcun valore dalla funzione nel caso in cui lo memorizzo in una variabile? – user435245

+0

Sì, lo fa. Vedi la mia risposta aggiornata. –

+2

Risposta migliore: http: // stackoverflow.it/questions/3061/calling-a-function-from-a-string-with-the-functions-name-in-python – Framester

37

Questo non è esattamente rispondere alla tua domanda, ma forse aiuta comunque:

Come accennato, eval dovrebbero essere evitati se possibile. Un modo migliore è usare il disimballaggio del dizionario. Questo è anche molto dinamico e meno soggetto a errori.

Esempio:

def fullName(name = "noName", family = "noFamily"): 
    return name + family 

functionList = {'fullName': fullName} 

function = 'fullName' 
parameters = {'name': 'Foo', 'family': 'Bar'} 

print functionList[function](**parameters) 
# prints FooBar 

parameters = {'name': 'Foo'} 
print functionList[function](**parameters) 
# prints FoonoFamily 
+3

+1 per non suggerire 'eval' – MAK

6

So che questa domanda è piuttosto vecchio, ma si potrebbe fare qualcosa di simile:

argsdict = {'name': 'Joe', 'family': 'Brand'} 
globals()['fullName'](**argsdict) 

argsdict è un dizionario di discussione, globals chiama la funzione utilizzando una stringa e ** espande il dizionario in un elenco di parametri. Molto più pulito di eval. L'unico problema sta nel dividere la corda. Una soluzione (molto disordinato):

example = 'fullName(name=\'Joe\',family=\'Brand\')' 
# Split at left parenthesis 
funcname, argsstr = example.split('(') 
# Split the parameters 
argsindex = argsstr.split(',') 
# Create an empty dictionary 
argsdict = dict() 
# Remove the closing parenthesis 
# Could probably be done better with re... 
argsindex[-1] = argsindex[-1].replace(')', '') 
for item in argsindex: 
    # Separate the parameter name and value 
    argname, argvalue = item.split('=') 
    # Add it to the dictionary 
    argsdict.update({argname: argvalue}) 
# Call our function 
globals()[funcname](**argsdict) 
+0

L'unica soluzione. Se questo codice dovesse risiedere in un modulo, e quel modulo verrebbe ricaricato dopo che il codice di 'fullName' è stato modificato, allora le modifiche saranno effettive nella prossima chiamata a' fullName'. La risposta di Felix Kling non ha questa proprietà in quanto la funzione è memorizzata nella cache in 'functionList', e non parleremo nemmeno di quanto sia pessima l'idea di 'eval'. –

Problemi correlati