web-dev-qa-db-fra.com

Utiliser un dictionnaire pour sélectionner la fonction à exécuter

J'essaie d'utiliser la programmation fonctionnelle pour créer un dictionnaire contenant une clé et une fonction à exécuter: 

myDict={}
myItems=("P1","P2","P3",...."Pn")
def myMain(key):
    def ExecP1():
        pass
    def ExecP2():
        pass
    def ExecP3():
        pass
        ...
    def ExecPn():
        pass  

Maintenant, j'ai vu un code utilisé pour trouver les fonctions définies dans un module, et je dois faire quelque chose comme ceci:

    for myitem in myItems:
        myDict[myitem] = ??? #to dynamically find the corresponding function

Ma question est donc la suivante: comment créer une liste de toutes les fonctions Exec et les affecter ensuite à l'élément souhaité à l'aide du dictionnaire? donc à la fin j'aurai myDict["P1"]() #this will call ExecP1()

Mon vrai problème est que j'ai des tonnes de ces éléments et que je crée une bibliothèque qui les gérera, l'utilisateur final n'aura qu'à appeler myMain("P1")

Je pense utiliser le module inspecter, mais je ne sais pas trop comment le faire.

Ma raison d'éviter:

def ExecPn():
    pass
myDict["Pn"]=ExecPn

c’est que je dois protéger le code car je l’utilise pour fournir une fonction de script dans mon application.

33
JohnnyDH

Pas fier, mais:

def myMain(key):
    def ExecP1():
        pass
    def ExecP2():
        pass
    def ExecP3():
        pass
    def ExecPn():
        pass 
    locals()['Exec' + key]()

Cependant, je vous recommande de les mettre dans un module/une classe, c'est vraiment horrible.

18
Ohad

Simplifier, simplifier, simplifier:

def p1(args):
    whatever

def p2(more args):
    whatever

myDict = {
    "P1": p1,
    "P2": p2,
    ...
    "Pn": pn
}

def myMain(name):
    myDict[name]()

C'est tout ce dont vous avez besoin.


Vous pouvez envisager d'utiliser dict.get avec une valeur par défaut appelable si name fait référence à une fonction non valide

def myMain(name):
    myDict.get(name, lambda: 'Invalid')()

(Pris cette astuce de Martijn Pieters)

66
S.Lott

Simplifier, simplifier, simplifier + DRY:

tasks = {}
task = lambda f: tasks.setdefault(f.__name__, f)

@task
def p1():
    whatever

@task
def p2():
    whatever

def my_main(key):
    tasks[key]()
17
Joe
# index dictionary by list of key names

def fn1():
    print "One"

def fn2():
    print "Two"

def fn3():
    print "Three"

fndict = {"A": fn1, "B": fn2, "C": fn3}

keynames = ["A", "B", "C"]

fndict[keynames[1]]()

# keynames[1] = "B", so output of this code is

# Two
2
jwc3119
#!/usr/bin/python

def thing_a(arg=None):
    print 'thing_a', arg

def thing_b(arg=None):
    print 'thing_b', arg

ghetto_switch_statement = {
    'do_thing_a': thing_a,
    'do_thing_b': thing_b
}

ghetto_switch_statement['do_thing_a']("It's lovely being an A")
ghetto_switch_statement['do_thing_b']("Being a B isn't too shabby either")

print "Available methods are: ", ghetto_switch_statement.keys()
1
synthesizerpatel

Ceci appellera des méthodes du dictionnaire

Ceci est une instruction de commutateur python avec appel de fonction

Créez quelques modules selon vos besoins ... Si vous voulez passer des arguments, passez.

Créez un dictionnaire, qui appellera ces modules selon les besoins.

    def function_1(arg):
        print("In function_1")

    def function_2(arg):
        print("In function_2")

    def function_3(fileName):
        print("In function_3")
        f_title,f_course1,f_course2 = fileName.split('_')
        return(f_title,f_course1,f_course2)


    def createDictionary():

        dict = {

            1 : function_1,
            2 : function_2,
            3 : function_3,

        }    
        return dict

    dictionary = createDictionary()
    dictionary[3](Argument)#pass any key value to call the method
0
akD

Vous perdez votre temps:

  1. Vous êtes sur le point d'écrire beaucoup de code inutile et d'introduire de nouveaux bogues.
  2. Pour exécuter la fonction, votre utilisateur devra tout de même connaître le nom P1.
  3. Etc., etc., etc. 

Il suffit de mettre toutes vos fonctions dans le fichier .py:

# my_module.py

def f1():
    pass

def f2():
    pass

def f3():
    pass

Et utilisez-les comme ceci:

import my_module

my_module.f1()
my_module.f2()
my_module.f3()

ou:

from my_module import f1
from my_module import f2
from my_module import f3

f1()
f2()
f3()

Cela devrait suffire pour commencer.

0
Misha Akovantsev

Vous pouvez simplement utiliser

myDict = {
    "P1": (lambda x: function1()),
    "P2": (lambda x: function2()),
    ...,
    "Pn": (lambda x: functionn())}
myItems = ["P1", "P2", ..., "Pn"]

for item in myItems:
    myDict[item]()
0
Jonas De Schouwer