2
votes

Méthodes stockées sous forme de chaînes dans des méthodes qui s'exécutent

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?


0 commentaires

6 Réponses :


3
votes

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 ()


5 commentaires

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 ()



2
votes

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}


0 commentaires

2
votes

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}


0 commentaires

4
votes

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()   


2 commentaires

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 .



1
votes

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"]()


2 commentaires

La boucle n'est pas non plus nécessaire: Want_variable = d ["a"] () .


C'est vrai, j'ai édité. Merci @chepner!.



0
votes

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)


7 commentaires

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.