Création de fonction dynamique Python avec des noms personnalisés

excuses si cette question a déjà été soulevée et a déjà reçu une réponse. Ce que je dois faire est très simple dans le concept, mais malheureusement je n'ai pas été en mesure de trouver une réponse en ligne.

je dois créer des fonctions dynamiques en Python (Python2.7) avec des noms personnalisés à l'exécution. Le corps de chaque fonction doit également être construit à l'exécution, mais il est (presque) le même pour toutes les fonctions.

je commence par une liste de noms.

func_names = ["func1", "func2", "func3"]

Notez que la liste func_name peut contenir une liste de noms arbitraires, de sorte que les noms ne seront pas simplement func1, func2, func3, ....

je veux que le résultat sera :

    def func1(*args):
        ...

    def func2(*args):
        ...

    def func3(*args):
        ...

la raison pour laquelle je dois faire ceci est que chaque nom de fonction correspond à un cas de test qui est alors appelé du monde extérieur.

mise à jour: il n'y a pas d'entrée utilisateur. J'attache deux bouts d'un module beaucoup plus grand. Une extrémité détermine ce que sont les cas de test et entre autres choses, popule une liste des noms des cas de test. L'autre extrémité est les fonctions elles-mêmes, qui doivent avoir une correspondance 1:1 avec le nom du cas d'essai. J'ai donc le nom du cas de test, je sais ce que je veux faire avec chaque cas de test, j'ai juste besoin de créer des fonctions qui ont le nom du cas de test. Puisque le nom des cas de test est déterminé à l'exécution, la création de la fonction basée sur ces cas de test doit être aussi à l'exécution.

mise à jour: je peux aussi envelopper cette coutume nomme des fonctions dans une classe si cela rendait les choses plus faciles.

je peux coder dur le contenu des fonctions (puisqu'elles sont presque identiques) dans une chaîne, ou je peux le baser à partir d'une classe de base précédemment définie. Juste besoin de savoir comment remplir les fonctions avec ce contenu.

Par exemple:

    func_content = """
                   for arg in args:
                       print arg
                   """

Merci d'avance,

Mahdi

30
demandé sur mahdiolfat 2012-11-01 23:38:25

5 réponses

pour ce que vous décrivez, Je ne pense pas que vous devez descendre dans eval ou macros - créer des instances de fonction par fermeture devrait fonctionner très bien. Exemple:

def bindFunction1(name):
    def func1(*args):
        for arg in args:
            print arg
        return 42 # ...
    func1.__name__ = name
    return func1

def bindFunction2(name):
    def func2(*args):
        for arg in args:
            print arg
        return 2142 # ...
    func2.__name__ = name
    return func2

cependant, vous voudrez probablement ajouter ces fonctions par nom à une certaine portée afin que vous puissiez y accéder par nom.

>>> print bindFunction1('neat')
<function neat at 0x00000000629099E8>
>>> print bindFunction2('keen')
<function keen at 0x0000000072C93DD8>
38
répondu Shane Holloway 2016-07-23 00:19:04

en prolongeant la réponse de Shane puisque je viens de trouver cette question en cherchant une solution à un problème similaire. Faites attention à la portée des variables. Vous pouvez éviter les problèmes de portée en utilisant une fonction de générateur pour définir la portée. Voici un exemple qui définit les méthodes d'une classe:

class A(object):
    pass

def make_method(name):
    def _method(self):
        print("method {0} in {1}".format(name, self))
    return _method

for name in ('one', 'two', 'three'):
    _method = make_method(name)
    setattr(A, name, _method)

en cours d'utilisation:

In [4]: o = A()

In [5]: o.one()
method one in <__main__.A object at 0x1c0ac90>

In [6]: o1 = A()

In [7]: o1.one()
method one in <__main__.A object at 0x1c0ad10>

In [8]: o.two()
method two in <__main__.A object at 0x1c0ac90>

In [9]: o1.two()
method two in <__main__.A object at 0x1c0ad10>
12
répondu Paul Whipp 2013-10-30 20:21:29

il y a probablement une sorte d'introspection pour faire ce genre de chose, mais je ne pense pas que ce serait l'approche pythonique du problème.

je pense que vous devriez profiter de la nature des fonctions en python en tant que citoyens de premier niveau. Utilisez les fermetures comme Shane Holloway l'a indiqué, pour personnaliser le contenu de la fonction comme vous le souhaitez. Puis pour la liaison de nom dynamique, utilisez un dictionnaire dont les clés sont les noms définis dynamiquement, et les valeurs seront les fonctions m'.

def function_builder(args):
    def function(more_args):
       #do stuff based on the values of args
    return function

my_dynamic_functions = {}
my_dynamic_functions[dynamic_name] = function_builder(some_dynamic_args)

#then use it somewhere else
my_dynamic_functions[dynamic_name](the_args)

j'Espère qu'il fait sens pour votre cas d'utilisation.

6
répondu Facundo Olano 2012-11-01 20:18:14

Vous pouvez utiliser eval; vous construirez la chaîne contenant la définition Python de chaque fonction (i.e. une chaîne multiligne commençant par def func1....) et vous serez alors eval.

mais je générerais un nom unique pour chacune de ces fonctions (par exemple