52 votes

Création de méthodes dynamiques/temps réel (génération de code) en Python

J'ai besoin de générer le code d'une méthode au moment de l'exécution. Il est important de pouvoir exécuter un code arbitraire et d'avoir une docstring.

J'ai trouvé une solution combinant exec y setattr Voici un exemple fictif :

class Viking(object):
    def __init__(self):
        code = '''
            def dynamo(self, arg):
                """ dynamo's a dynamic method!
                """
                self.weight += 1
                return arg * self.weight
            '''
        self.weight = 50

        d = {}
        exec code.strip() in d
        setattr(self.__class__, 'dynamo', d['dynamo'])

if __name__ == "__main__":
    v = Viking()
    print v.dynamo(10)
    print v.dynamo(10)
    print v.dynamo.__doc__

Existe-t-il un moyen meilleur / plus sûr / plus idiomatique d'obtenir le même résultat ?

0 votes

Pourquoi avez-vous besoin de cela, avez-vous considéré les autres facilités de métaprogrammation de Python ?

0 votes

Je suis ouvert aux suggestions :-) J'en ai besoin pour générer des règles pour PLY, qui en a besoin en tant que méthodes avec des docstrings. Pour automatiser un peu de code standard, je peux générer des règles dans une boucle au moment de l'exécution.

0 votes

Pouvez-vous donner un meilleur exemple ou expliquer davantage ? L'exemple que vous donnez n'est pas très dynamique puisqu'il s'agit d'une chaîne codée en dur, j'ai du mal à comprendre pourquoi vous ne pouvez pas utiliser les répartiteurs, le polymorphisme, les métaclasses, etc.

-1voto

desdulianto Points 1

Pardonnez-moi pour mon mauvais anglais.

J'ai récemment eu besoin de générer une fonction dynamique pour lier chaque élément de menu à l'ouverture d'un cadre particulier sur wxPython. Voici ce que je fais.

Tout d'abord, je crée une liste de correspondances entre l'élément de menu et le cadre.

menus = [(self.menuItemFile, FileFrame), (self.menuItemEdit, EditFrame)]

le premier élément de la cartographie est l'élément de menu et le dernier élément est le cadre à ouvrir. Ensuite, je lie l'événement wx.EVT_MENU de chaque élément du menu à un cadre particulier.

for menu in menus:
    f = genfunc(self, menu[1])
    self.Bind(wx.EVT_MENU, f, menu[0])

La fonction genfunc est le constructeur de fonctions dynamiques, dont voici le code :

def genfunc(parent, form):
    def OnClick(event):
        f = form(parent)
        f.Maximize()
        f.Show()
    return OnClick

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