IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Génération de code


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Par défaut Génération de code
    Une question qui semble revenir assez régulièrement dans ces forums est "comment exécuter du code au run-time?"

    Voici une façon de créer des fonctions au run-time. Voici un exemple de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    def _color(text, color):
        print '<font color="%s">%s</font>' % (color, text)
     
    colors = {
        'red'  : '#ff0000',
        'green': '#00ff00',
        'blue' : '#0000ff',
    }
     
    for color, code in colors.iteritems():
        locals()[color] = lambda text: _color(text, code)
     
    red("RED")
    blue("BLUE")
    green("GREEN")
    Et à l'exécution:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $ python colors.py
    <font color="#ff0000">RED</font>
    <font color="#0000ff">BLUE</font>
    <font color="#00ff00">GREEN</font>
    Donc, voyons le fonctionnement. La fonction _color() prend deux argument, un texte et un code de couleur. Donc, pour écrire en rouge, on ferait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    _color('Hello', '#ff0000')
    Par contre, ça risque de devenir rapidement long à écrire. Ce qu'on voudrait c'est avoir une fonction red() qui écrit en rouge. On pourrait certainement la créer, et faire de même avec green() et blue(). Le problème est que si on décide de faire une modification, par exemple ajouter un paramètre class à FONT, il faudra changer 3 fonctions. C'est pas super intéressant.

    Donc ce que nous allons faire, c'est générer programmatiquement les fonctions red(), green() et blue() en se servant de _color(). Donc, si on change _color(), les trois autres fonctions vont être mises à jour également.

    La première chose à faire est d'écrire notre fonction _color(). Je ne m'y attarde pas, je crois que c'est assez simple. Ensuite, dans un dictionnaire, on fait un mapping entre le nom de notre fonction spécialisé et son code de couleur. Encore là, je crois que c'est assez simple, donc je passe.

    On arrive maintenant à la partie "magique" du code. La fonction locals() retourne un dict qui contient les différents identificateurs locaux. Si on faisait un print à ce point-ci, on verrait que _color et colors sont dans les clés. Il est possible de modifier ce qui se trouve dans locals(), donc on a la ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        locals()[color] = lambda text: _color(text, code)
    Ce qui arrive, on ajoute dans locals() un mapping entre le nom de la couleur et une fonction d'un argument (le texte) qui appelle _color() avec le texte donné en paramètre et le code de couleur pris de colors.

    Une fois que c'est fait, on peut utiliser red(), green() et blue() comme si on les avait définit avec def.

  2. #2
    Membre confirmé
    Avatar de Zorro
    Inscrit en
    Août 2002
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 137
    Par défaut
    pour ces explications

    Z

  3. #3
    Membre expérimenté
    Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2005
    Messages : 161
    Par défaut
    On peut aussi faire comme ça a partir de Python 2.5

    en début de script

    et la boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for color, code in colors.iteritems():
        locals()[color] = functools.partial(_color, color=code)
    Ça fait la même chose mais c'est peut être un peu plus simple à relire.

  4. #4
    Membre émérite
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Par défaut
    poof: je l'avais écrit comme ça au début, mais j'ai décidé d'aller avec lambda pour le bénéfice des gens encore sur Python 2.2, 2.3, 2.4, ...

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Attention; modifier locals() ne fonctionne qu'au top-level du module (il est alors un synonyme de globals() je pense); dans une fonction locals() renvoie une copie du namespace et le modifier n'a donc aucun effet.
    Donc, je pense qu'il vaudrait mieux modifier globals() que locals(), afin d'éviter de tomber dans le piège le jour où on essaie de le modifier dans une fonction.

Discussions similaires

  1. Génération de code & bpm4struts
    Par k4eve dans le forum BPM
    Réponses: 3
    Dernier message: 08/03/2007, 15h12
  2. Modelisation UML / Génération de code C++ sous eclipse
    Par silverhawk.os dans le forum Eclipse C & C++
    Réponses: 5
    Dernier message: 03/01/2006, 00h15
  3. [UML] génération de code avec omondo.uml
    Par RENAULT dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 31/10/2003, 13h14
  4. [Lomboz] Génération de code pour EJB
    Par paikan dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 09/07/2003, 14h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo