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 :

Système de script souple avec eval()


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2011
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 51
    Par défaut Système de script souple avec eval()
    Bonsoir,

    J'aimerai réaliser et utiliser un système de scripts qui aurait le comportement suivant :
    Charger dans un dict tout les fichiers contenus dans un dossier contenant chacun une réimplémentation d'une classe.

    Je ne sais pas si cela veut dire quelque-chose ou pas, mais je pense que des exemples seront beaucoup plus parlants à vous comme à moi :

    Voici la classe abstraite AbstractBlock qui comporte peut d’éléments (c'est juste pour l'exemple) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class AbstractBlock:
        def __init__(self):
            pass
     
        def onCross(self, vehicle):
            pass
    Et voici par exemple un fichier "grass_radioactive.block" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class GrassRadioactiveBlock(AbstractBlock):
        def __init__(self):
            pass
     
        def onCross(self, vehicle):
            vehicle.damage(10)
    Comme vous pouvez le constater, le fichier "grass_radioactive.block" ne comporte pas d'include vers la classe AbstractBlock, car en effet je veux que ce soit un fichier de script et donc qu'il se limite au minimum et que les import se fassent en interne, pas dans le script. Je pourrais toujours rajouter le "import" dans la chaine de caractère avant de la passer à eval().

    De plus, une fois tout les fichiers chargés, je voudrais avoir un dict contenant pour clé le nom du fichier (sans l'extension) et comme valeur la classe contenue dedans, par exemple ici mon dict peut être représenté comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    blocks = {"radioactive_grass": RadioactiveGrassBlock}
    Je ne sais pas si cette méthode est trop dure à implémenter (à priori non à l'aide de eval()) ni si elle est "sâle" ou pas, mais je tiens absolument à séparer les fichiers de script du "moteur" du jeu.

    Auriez vous déjà des idées pour charger ces classes dans le dict ? Car je ne vois pas comment faire avec eval()...
    Merci d'avance pour vos éventuelles remarques et réponses

  2. #2
    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
    eval évalue une expression, mais ici c'est une bloc d'instructions et c'est donc plutôt exec qu'il faut utiliser (ou, dans ton cas, execfile est sans doute plus approprié).

    Ajouter une instruction import ... n'est pas nécessaire, tu peux passer un dictionnaire en argument (globals) à eval/exec/execfile qui contient déjà le module nécessaire chargé.

    Pour récupérer la classe après exécution, à priori je pense à parcourir le dictionnaire passé en globals au script à la recherche d'une sous-classe de AbstractBlock.

    Si le principe est de permettre aux utilisateurs de scripter ton application, c'est bien sûr très dangereux d'exécuter du code python arbitraire, mais je suppose que tu es conscient de ça...

  3. #3
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Bonsoir.

    Citation Envoyé par dividee Voir le message
    ... c'est bien sûr très dangereux d'exécuter du code python arbitraire, mais je suppose que tu es conscient de ça...
    eval is evil !

  4. #4
    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
    Citation Envoyé par rambc Voir le message
    eval is evil !
    Bert is evil! go back!
    (pour ceux qui comprennent )

  5. #5
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    Comme ceci ?
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #!/usr/bin/env python
    # -*- coding: ISO8859-1 -*-
    #
    #
    class AbstractBlock:
        def __init__(self):
            pass
     
        def onCross(self, vehicle):
            pass
     
    grass_radioactive = """class GrassRadioactiveBlock(AbstractBlock):
        def __init__(self):
            pass
     
        def onCross(self, vehicle):
            return vehicle"""
     
    exec(grass_radioactive) # Ou execfile si c'est un fichier
     
    blocks = {"radioactive_grass": GrassRadioactiveBlock}
     
    inst = blocks['radioactive_grass']()
    print(inst.onCross('Patin à roulette'))
    print(inst)
    Mais bon... Utiliser exec/eval pour du code Python...
    Vous devriez suivre le conseil de dividee et penser à un autre système.

    @+

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Février 2011
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 51
    Par défaut
    Merci pour vos réponses, j'irai faire un tour sur la doc pour exec et execfile

    Sinon, je suis conscient des risques mais le jeu sera lui-même opensource, alors entre mettre des failles dans le code source ou dans les scripts, je vois pas trop la différence. Sur un plan technique, on peut imaginer un site officiel qui distribue les "extensions" (ensemble de scripts et textures) qui vérifie ces extensions avant de les publier.
    Non, pour moi, cela n'introduit pas trop de grosses failles, je ne vois pas l'intérêt de mettre des failles dans les scripts alors que ce serai plus simple dans le code source

    Sinon, au niveau du script, j'aimerai alléger le plus possible les fichiers de script. Prenons ici le fichier d'extension .block précedent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class GrassRadioactiveBlock(AbstractBlock):
        def __init__(self):
            pass
     
        def onCross(self, vehicle):
            vehicle.damage(10)
    Il pourrait alors devenir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def __init__(self):
    	pass
     
    def onCross(self, vehicle):
    	vehicle.damage(10)
    Le nom de la classe n'ayant pas d'importance (car gestion par dictionnaire), il pourra être généré par le nom du fichier. Je veux vraiment que l'on évite les détails techniques dans les scripts (redéclarer une classe à chaque fois me parait abusif pour le scripteur ).

    Mais bon, je fonce tête baissée dans mon idée mais je ne sais pas du tout si elle sera maintenable dans le temps et pas trop compliquée à mettre en place. J'attends donc vos avis sur ce système en lui même, si on exclue bien sûr les éventuelles failles de sécurité (comme j'en ai parlé plus haut).

    Merci pour vos réponses

    EDIT :

    Vous devriez suivre le conseil de dividee et penser à un autre système.
    Je n'ai pas compris ce conseil
    Mais sinon, qu'avez vous d'autre à proposer ? Garder du code python générique et s'embêter à faire des import en boucle ?

  7. #7
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Citation Envoyé par darkrojo Voir le message
    Sinon, au niveau du script, j'aimerai alléger le plus possible les fichiers de script. Prenons ici le fichier d'extension .block précedent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class GrassRadioactiveBlock(AbstractBlock):
        def __init__(self):
            pass
     
        def onCross(self, vehicle):
            vehicle.damage(10)
    Il pourrait alors devenir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def __init__(self):
    	pass
     
    def onCross(self, vehicle):
    	vehicle.damage(10)
    Le nom de la classe n'ayant pas d'importance (car gestion par dictionnaire), il pourra être généré par le nom du fichier. Je veux vraiment que l'on évite les détails techniques dans les scripts (redéclarer une classe à chaque fois me parait abusif pour le scripteur )
    Dans ce cas autant éviter Python et passer directement par un fichier de configuration avec section. Comprendre (par exemple)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [onCross]
    vehicle.damage = 10
    A vous de traiter le fichier avec Python dans votre code

    Sinon, comme dirait dividee, You've been warned

  8. #8
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Citation Envoyé par dividee Voir le message
    Bert is evil! go back!
    (pour ceux qui comprennent )
    Moi pas comprendre...

  9. #9
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Citation Envoyé par rambc Voir le message
    Moi pas comprendre...
    Bah, moi non plus…

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Système] Exécution d'un script SHELL avec PHP
    Par diabli73 dans le forum Langage
    Réponses: 5
    Dernier message: 02/10/2008, 15h07
  2. [Système] Lancer un script perl avec PHP
    Par pepite dans le forum Langage
    Réponses: 2
    Dernier message: 09/01/2006, 12h30
  3. Réponses: 6
    Dernier message: 23/05/2005, 08h33
  4. Script SQL avec des EXIT SQL.SQLCODE
    Par fidififouille dans le forum Oracle
    Réponses: 14
    Dernier message: 23/04/2004, 16h45
  5. Génération de script SQL avec les données
    Par borgfabr dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 05/03/2004, 13h57

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