74 votes

Comment appeler des fonctions Python de manière dynamique

J'ai ce code :

fields = ['name','email']

def clean_name():
    pass

def clean_email():
    pass

Comment puis-je appeler clean_name() y clean_email() dynamiquement ?

Par exemple :

for field in fields:
    clean_{field}()

J'ai utilisé les accolades parce que c'est ainsi que je le faisais en PHP, mais cela ne fonctionne évidemment pas.

Comment faire cela avec Python ?

6voto

demas Points 10567

Voici un autre moyen :

myscript.py :

def f1():
    print 'f1'

def f2():
    print 'f2'

def f3():
    print 'f3'

test.py :

import myscript

for i in range(1, 4):
    getattr(myscript, 'f%d' % i)()

4voto

Muhammad Shahbaz Points 139

J'avais besoin d'appeler différentes méthodes d'une classe dans une méthode d'elle-même sur la base d'une liste de noms de méthodes passés en entrée (pour exécuter des tâches périodiques dans FastAPI). Pour exécuter les méthodes des classes Python, j'ai étendu la réponse fournie par @khachik. Voici comment vous pouvez le réaliser depuis l'intérieur ou l'extérieur de la classe :

>>> class Math:
...   def add(self, x, y):
...     return x+y
...   def test_add(self):
...     print(getattr(self, "add")(2,3))
... 
>>> m = Math()
>>> m.test_add()
5
>>> getattr(m, "add")(2,3)
5

Regardez attentivement comment vous pouvez le faire à partir de la classe en utilisant self comme ça :

getattr(self, "add")(2,3)

Et de l'extérieur de la classe en utilisant un objet de la classe comme ceci :

m = Math()
getattr(m, "add")(2,3)

3voto

Spacedman Points 33792

Voici une autre solution : définissez les fonctions puis définissez un dict avec les noms comme clés :

>>> z=[clean_email, clean_name]
>>> z={"email": clean_email, "name":clean_name}
>>> z['email']()
>>> z['name']()

puis on boucle sur les noms en tant que clés.

ou que diriez-vous de celui-là ? Construisez une chaîne de caractères et utilisez 'eval' :

>>> field = "email"
>>> f="clean_"+field+"()"
>>> eval(f)

puis il suffit de boucler et de construire les chaînes de caractères pour eval.

Notez que toute méthode qui nécessite la construction d'une chaîne de caractères pour l'évaluation est considérée comme kludgy.

2voto

Matt Joiner Points 29194
for field in fields:
    vars()['clean_' + field]()

1voto

martineau Points 21665

J'utiliserais un dictionnaire qui mettrait en correspondance les noms de champs avec les fonctions de nettoyage. Si certains champs n'ont pas de fonction de nettoyage correspondante, l'option for La gestion des boucles peut être simplifiée en fournissant une sorte de fonction par défaut pour ces cas. Voici ce que je veux dire :

fields = ['name', 'email', 'subject']

def clean_name():
    pass
def clean_email():
    pass

# (one-time) field to cleaning-function map construction
def get_clean_func(field):
    try:
        return eval('clean_'+field)
    except NameError:
        return lambda: None  # do nothing
clean = dict((field, get_clean_func(field)) for field in fields)

# sample usage
for field in fields:
    clean[field]()

Le code ci-dessus construit le dictionnaire de fonctions de manière dynamique en déterminant si une fonction correspondante nommée clean_<field> existe pour chaque personne nommée dans le fields liste. Vous n'aurez probablement à l'exécuter qu'une seule fois puisqu'elle restera la même tant que la liste des champs ou les fonctions de nettoyage disponibles ne seront pas modifiées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X