J'avais un dictionnaire comme celui-ci:
for key,value in dictionary.items():
if key == something:
wanted_variable = value
Mais comme je ne veux pas que toutes mes fonctions s'exécutent lorsque je déclare le dictionnaire, je les ai stockées sous forme de chaînes:
XXX
Ce que je voulais faire était d'appeler une seule fonction en fonction de la clé qui lui est associée:
dictionary = { "a":"function_1()", "b":"function_2()", "c":"function_3()"}
Si j'imprime la variable souhaitée maintenant il retournera "function_1 ()", et je veux que ce soit ce que function_1 () renvoie ...
Quelqu'un peut-il m'aider s'il vous plaît?
6 Réponses :
Vous pouvez stocker des fonctions sans faire d'appel:
if something in dictionary:
wanted_variable = dictionary[something]()
Et après
for key, value in dictionary.items():
if key == something:
wanted_variable = value()
Au fait, il existe un moyen plus efficace d'obtenir wanted_variable:
dictionary = { "a":function_1, "b":function_2, "c":function_3} # no ()
Vous pouvez également utiliser " Want_variable = dictionary [quelque chose] () " au lieu de la comparaison en boucle
Je ne peux pas si le dictionnaire ne contient pas quelque chose
Ensuite, vérifiez simplement si quelque chose est dans le dictionnaire; pas besoin de parcourir toutes les clés en premier. si quelque chose dans le dictionnaire: voulu_variable = dictionnaire [quelque chose] () .
Nous copions tous l'exemple de code d'OP, mais vous avez raison, j'ai mis à jour ma réponse
Dans la première vous avez vérifié le dictionnaire n fois, dans la dernière vous le vérifiez deux fois, mais vous pouvez le vérifier une fois avec quelque chose comme func = dictionary.get ( quelque chose); si func: func ()
Vous devez définir le dictionnaire avec uniquement des noms de fonction:
for key, value in dictionary.items():
if key == 'a':
wanted_variable = value()
Si vous encapsulez la paranthèse après le nom de la fonction, vous l'appelez immédiatement.
Appelez la fonction requise correspondant comme :
dictionary = {"a":function_1, "b":function_2, "c":function_3}
Vous pouvez simplement stocker les fonctions sans les appeler:
for key,value in dictionary.items():
if key == something:
wanted_variable = value()
Ensuite:
dictionary = { "a":function_1, "b":function_2, "c":function_3}
Les fonctions étant des objets de première classe, vous pouvez leur transmettre des références sans les appeler, et les appeler plus tard:
from functools import partial
def foo(x):
print("x is", x)
wrapped_foo = partial(foo, 123)
# Pass wrapped_foo around however you want...
d = {'func': wrapped_foo}
# Call it later
d['func']() # Prints "foo is 123"
Alternativement,
from functools import partial
dictionary = {
"a":partial(function_1, 123),
"b":partial(function_2, 456),
"c":partial(function_3, 789),
}
for key,value in dictionary.items():
if key == something:
# "Calling" parens here, not in the dictionary values
# This will actually call, for example, function_1(123).
wanted_variable = value()
La boucle n'est pas nécessaire; une seule clé peut correspondre à quelque chose , il suffit donc d'indexer directement le dictionnaire.
@chepner Je me concentrais sur la question de l'OP mais bonne prise - j'ai ajouté une alternative sous le premier bloc en utilisant dict.get .
Vous pouvez stocker des fonctions sans () pour qu'elles ne s'exécutent pas, alors vous pouvez faire:
def func1():
x = "func1"
print(x)
return x
def func2():
x = "func2"
print(x)
return x
d = {"a":func1, "b":func2}
wanted_variable = d["a"]()
La boucle n'est pas non plus nécessaire: Want_variable = d ["a"] () .
C'est vrai, j'ai édité. Merci @chepner!.
eval est une réponse plus simple et plus réelle à votre question.
dictionary = { "a":"function_1()", "b":"function_2()", "c":"function_3()"}
for key, value in dictionary.items():
if key == something:
wanted_variable = eval(value)
Vous n'avez pas besoin de eval at all si vous stockez des références aux fonctions dans le dictionnaire.
J'ai stocké les fonctions sous forme de chaîne dans le dictionnaire. Pas réf. Cela ne fonctionnerait-il pas?
Ouais. Ne fais pas ça.
@chepner c'est en fait le cas exact que pose la question. Même si je suis d'accord que ce n'est pas la meilleure approche (voir l'autre réponse) et que votre commentaire est également valable, je pense que c'est une réponse valable et correcte
Oui. J'ai aussi obtenu la sortie comme prévu.
OK, le vote négatif est rétracté, mais n'encourage pas vraiment les mauvais comportements. Il est fort probable que les cordes aient été le propre choix de l'OP, ce n'est pas une mauvaise conception qui leur a été imposée.
Merci. Je l'ai.