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 :

Stocker test conditionnel dans un attribut d'objet


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut Stocker test conditionnel dans un attribut d'objet
    Bonjour à tous,

    Je souhaiterais créer un objet qui puisse contenir, (passée en argument lors de sa création), une condition qui doit être vérifiable en temps réel à tout moment.

    Exemple :


    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
    class Testeur() :
       def __init__ (self, condition) :
           self.condition = condition
           self.resultat = False
     
       def tester(self) :
           if self.condition :
              self.resultat = True
           else :
             self.resultat = False
     
     
    a = 1
     
    testeur = Testeur(condition = a < 0)
     
    print("Le résultat est : ", testeur.tester()) ##doit afficher False
     
    a = -2
     
    print("Le résultat est : ", testeur.tester()) ##doit afficher True



    Y-a-t-il une solution technique qui m'éviterait de devoir passer la condition en argument à chaque appel de la méthode "tester()" ?

    Pour l'instant je m'aperçois que ce n'est pas la condition elle-même avec des alias ou des références d'objets qui sont passées en argument mais le résultat lui même en boolean.

    Merci par avance pour vos conseils et pistes de réflexion.

    A +

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    Je n'aime pas "eval" lorsqu'on lui donne a manger des entrées/sorties. Interagir avec l’extérieur est un trou de sécurité ou dans les fonctionnalités mal couvertes de l'applicaction.
    Ici, l'appel a "eval" est sans danger: on sait ce qu'on lui demande de faire: eval("a < 1").

    Mais je n'ai pas de moins mauvaise solution.
    Enfin, après il faut faire de la POO, c'est tout de suite plus complique.

    En fait "a" est une variable "globale".
    En Python, c'est un chemin d’accès a l'objet référence par "a" - notons ça /globals()['a']/.

    Manque de bol, les assignations "a = object" font que l’accès, via le chemin /globals()['a']/", trouvera un autre objet.
    "ré-évaluer la condition" passe par récupérer ce nouvel objet, i.e. parcourir le chemin: eval fait cela simplement.

    Ceci dit, pas de soucis, le code est simple.
    Pourquoi ça marche? Essentiellement parce que Python est un langage de scripting. Avec Bash, on peut évaluer des instructions a la volée. Python permet de compiler et d’exécuter a la volée.
    note: on sait aussi faire ça en assembleur. ce n'est pas liée au langage mais a la machine abstraite qui est dessous.

    C'est très surprenant.
    Il faut juste éviter d'en abuser: a n'utiliser que dans les cas désespérés.

    Enjoy!

    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
    class Testeur() :
        def __init__ (self, condition) :
            self.condition = condition
            self.resultat = False
     
        def tester(self) :
            self.resultat = eval(self.condition)
            return self.resultat
     
    if __name__ == '__main__':
        a = 1
        testeur = Testeur(condition="a < 0")   
        print("Le resultat est : ", testeur.tester()) ##doit afficher False
        a = -2
        print("Le resultat est : ", testeur.tester()) ##doit afficher True
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    Merci beaucoup pour votre réponse qui est exactement ce qu'il me fallait !

    J'en conclus que, si les conditions de "test" sont expréssément définies à l'avance, il n'y a pas de faille de sécurité dans une application ?

    D'autre part, pour aller plus loin, dans un pareil cas, comment vous y prendriez-vous pour effectuer ce genre de fonction "proprement" avec la POO ?

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    Pour ne pas utiliser "eval" dans ce cas la, Python dispose de la fonction lambda. Plutot qu'ecrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        condition = 'a < 0'
        a = 1
        assert eval(condition) is False
        a = -1
        assert eval(condition) is True
    On peut faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        condition = lambda: a < 0
        a = 1
        assert condition() is False
        a = -1
        assert condition() is True
    D'autre part, pour aller plus loin, dans un pareil cas, comment vous y prendriez-vous pour effectuer ce genre de fonction "proprement" avec la POO ?
    Vous constatez que "class Testeur..." est sans rapport avec la solution qui relève plutôt de la programmation fonctionnelle.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre chevronné Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Par défaut
    Bonjour,
    Je ne comprends pas bien votre classe, en particulier ce que vient faire l'attribut resultat. Il ne faut pas hésiter en Python à faire de la programmation fonctionnelle basique, une condition est, comme une comparaison, une fonction, et une fonction est un objet comme un autre. Je vous propose à triturer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Testeur() :
        def __init__ (self, condition) :
            self.condition = condition
     
        def tester(self, x) :
            return self.condition(x)
     
    for condition in (lambda x: x < 0 # strictement négatif
                    , lambda x: x >= 10 and x < 20 # entre 10 et 19
                    , lambda x: isinstance(x, float) or x + 122 == 133):# un float OU 11
        testeur = Testeur(condition = condition)
        for a in (10, 8, 0, -10, 11, 16, 20.0, 100):
            print(u"Pour %s le résultat est : %s" % (a, testeur.tester(a)))
        print 45 * '-'
    Attention à éviter des trucs genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if condition:
        a = True
    else:
        a = False
    au profit de
    Si condition (mal nommé alors) n'est pas un booléen, mais que vous comptez sur la traduction en booléen par python, utilisez bool(), voire not not ou autre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for x in (-2, 0, 1.1, "0", "", "21", "0zorglub", "zorglub", "zorglub0"):
        print u"%s -> %s  %s" % (x, bool(x), not not x)

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    Merci à tous pour vos réponses, je vais prendre le temps de les étudier.

    En tout cas merci, mon problème est résolu et j'en ai appris plus que ce que j'espérais !

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 290
    Par défaut
    Citation Envoyé par luluunix Voir le message
    D'autre part, pour aller plus loin, dans un pareil cas, comment vous y prendriez-vous pour effectuer ce genre de fonction "proprement" avec la POO ?
    Pas forcément avec la POO, mais en Python, je passerais la fonction de test au constructeur, potentiellement sous forme de lambda. Voici une forme générique.

    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
     
    #!/usr/bin/env python
    #-*- coding: utf-8 -*-
     
     
    class Testeur():
        def __init__(self, condition):
            self.condition = condition
            self.resultat = False
     
        def tester(self, *args):
            self.resultat = self.condition(*args)
            return self.resultat
     
    def main():
        a = 1
        b = -10
        testeur = Testeur(lambda x: x < 0)
        print("Le resultat est : " +  str(testeur.tester(a)))
        print("Le resultat est : " +  str(testeur.tester(b)))
     
    if __name__ == '__main__':
        main()

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

Discussions similaires

  1. afficher le résultat d'un test conditionnel dans un cout
    Par jfjobidon dans le forum Débuter
    Réponses: 4
    Dernier message: 27/04/2015, 16h40
  2. Réponses: 2
    Dernier message: 09/01/2013, 08h58
  3. test conditionnel dans un champ calculé
    Par funkyjul dans le forum Développement
    Réponses: 2
    Dernier message: 17/12/2008, 16h16
  4. Test conditionnel dans une JSP
    Par phpaide dans le forum Struts 1
    Réponses: 9
    Dernier message: 07/02/2007, 17h53
  5. Réponses: 4
    Dernier message: 20/07/2006, 10h35

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