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 :

Evenement "changement de valeur d'une variable"


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2011
    Messages : 45
    Par défaut Evenement "changement de valeur d'une variable"
    Bonjour,

    J'imagine que ce sujet a déjà été abordé dans ce forum, mais difficile à formuler, les critères de recherche que j'ai utilisés ne m'ont donné aucun résultat.

    Ma question est donc la suivante:

    Est-il possible "d'écouter" une variable pour déclencher un événement lorsque sa valeur change ? Mes investigations sur le web semblent répondre par la négative, mais un seul contre-exemple suffirait à prouver le contraire.

    Si quelqu'un a ce contre-exemple, ou peut m'expliquer pourquoi cette fonctionnalité ne peut exister, je lui en saurai gré.

    Merci d'avance.

    G CAPLANDE

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    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 738
    Par défaut
    Salut,

    Citation Envoyé par Caplande Voir le message
    Est-il possible "d'écouter" une variable pour déclencher un événement lorsque sa valeur change ? Mes investigations sur le web semblent répondre par la négative, mais un seul contre-exemple suffirait à prouver le contraire.
    Tout dépend de ce qu'on appelle "variable" et de l'objet auquel elle correspond.
    Une réalisation de ce type de variable est par exemple les "variables" Tkinter qui font exactement ça.

    - W
    PS: En POO, ce genre d'objet réalise peu ou prou le pattern observer
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Caplande Voir le message
    Si quelqu'un a ce contre-exemple, ou peut m'expliquer pourquoi cette fonctionnalité ne peut exister, je lui en saurai gré.
    Tout à fait.
    En fait tout tient dans le rôle d'une variable. Une variable est avant tout faite pour mémoriser une information afin de pouvoir la réutiliser plus tard. Cette information est donc à l'initiative du développeur qui choisit de la mettre à jour selon les circonstances. Il connait donc les circonstances qui entrainent la mise à jour, il n'a donc pas besoin de "surveiller" la variable puisque c'est lui qui la met à jour.

    Donc ton problème se situe, à mon avis, plus en amont. Un exemple : imagine que tu crées un capteur audio qui s'active quand il entend un son. Dans ce cas il met des variables à jour évidemment. Ce qu'il faut, c'est donc surveiller non pas la variable mais l'activation qui entraine sa mise à jour.
    Ce mécanisme simpliste de surveillance non pas d'une variable mais d'un évènement peut s'élargir dans, comme l'a dit wiztricks, dans un "observateur" => ici expliqué de façon plus détaillée.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2011
    Messages : 45
    Par défaut Evenement "changement de valeur d'une variable"
    Merci à vous deux. Je vais me pencher sur le sujet.

    CAPLANDE

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    J'aurais dit @property mais j'ai peut-être mal compris la question ...

  6. #6
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 323
    Par défaut
    bonjour

    @property c'est uniquement pour des attributs de classe et ici on ne connait pas le contexte de la question donc pas possible de répondre.
    A la place d'un setter, je suis plus pour un descripteur (même chose les 2). Et utiliser un setter n'est qu'une petite partie de la réponse

    Exemple simple avec un descripteur : On attache des fonctions de callback à un attribut. Pour faire un peu étoffer, ici, on attache soit des fonctions, soit des méthodes.

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    #!/bin/env python
     
    """
    Utiliser un descripteur ...
    https://docs.python.org/fr/3/howto/descriptor.html
    """
     
    import random
     
     
    class EstObserve:
        def __init__(self, funcs=None, instances=None):
            """
            funcs : [function] : envoi notif vers function()
            instances: [str] : envoi notif vers instanceclasse.on_event()
            """
            if not funcs:
                funcs = []
            self.callbacks = funcs
            if not instances:
                instances = []
            self.instances = instances
     
        def __set_name__(self, owner, name):
            self.name = "__" + name
     
        def __get__(self, obj, objtype=None):
            return getattr(obj, self.name)
     
        def __set__(self, obj, value):
            # print(f" update ..{self.name[2:]} en : {value}")
            setattr(obj, self.name, value)
            for call in self.callbacks:
                call(self.name[2:], getattr(obj, self.name))
            for call in self.instances:
                try:
                    getattr(obj, call).on_event(self.name[2:], value)
                except AttributeError:
                    pass
     
     
    def ecouteur(name, data):
        print(f"\t# receveur: var {name} == {data}")
     
     
    def ecouteur2(name, data):
        print(f"\t# est {'mineur' if data < 18 else 'majeur'}")
        # if data < 18: exit(8)
     
     
    class DataBase:
        """ devrait exister une interface """
        def on_event(self, name, data):  # méthode obligatoire avec cette signature
            print("\t# update dans bd ...")
     
     
    class Personne:
        age = EstObserve(
            funcs=[ecouteur, ecouteur2],
            instances=["db"]
        )
     
        def __init__(self, age) -> None:
            self.age = age
            self.db = DataBase()  # recoit notif si age change
     
     
    if __name__ == "__main__":
        moi = Personne(18)
        for _ in range(10):
            moi.age = random.randint(16, 21)
            print(f" Nouvel Age est: {moi.age}")
            print()

  7. #7
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2011
    Messages : 45
    Par défaut
    Bonjour papajoker,

    Très élaborée votre proposition, mais, si j'ai bien compris son fonctionnement, on revient au point de départ et à la remarque de Sve@r relative à la cause de l'événement.
    J'ai donc mal formulé ma question:
    Soit un programme quelconque dans lequel j'utilise une variable i (pour une itération par exemple). Je voudrais savoir s'il est possible d'attacher un événement à cette variable, événement qui se déclenche chaque fois qu'elle change de valeur.
    Alors,bien évidemment si i est l'index d'une itération, je maîtrise la cause de son changement et je peux associer le callback à chaque boucle d'itération.
    Mais si ce n'est le cas, ne peut-on associer un objet à i et activer sur cet objet un écouteur du type OnChange comme cela existe dans d'autres langages ?

  8. #8
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Hello,

    Encore une fois la question du PO n'est pas claire, mais elle le devient beaucoup plus dans sa réponse suivante, et à mon sens la réponse donnée par @josmiley semble être une des solutions que j'avais imaginé.

    Soit un programme quelconque dans lequel j'utilise une variable i (pour une itération par exemple). Je voudrais savoir s'il est possible d'attacher un événement à cette variable, événement qui se déclenche chaque fois qu'elle change de valeur.
    Alors,bien évidemment si i est l'index d'une itération, je maîtrise la cause de son changement et je peux associer le callback à chaque boucle d'itération.
    Mais si ce n'est le cas, ne peut-on associer un objet à i et activer sur cet objet un écouteur du type OnChange comme cela existe dans d'autres langages ?
    En étayant les propos de @josmiley, je voyais bien ce type d'écouteur sous forme de @property.

    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
    26
    27
    28
    29
    import random
     
    class ValueChangeListener:
        def __init__(self, initial_value=None):
            self._value = initial_value
     
        @property
        def value(self):
            return self._value
     
        @value.setter
        def value(self, new_value):
            if new_value != self._value:
                self._value = new_value
                self.on_value_change(new_value)
     
        def on_value_change(self, new_value):
            print(f"Value changed to: {new_value}")
     
     
    first_value, *values = [random.randint(1, 10) for _ in range(5)]
    listener = ValueChangeListener(first_value)
    for i in values:
        listener.value = i
     
    # Value changed to: 6
    # Value changed to: 5
    # Value changed to: 6
    # Value changed to: 9

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    En étayant les propos de @josmiley, je voyais bien ce type d'écouteur sous forme de @property.
    Oui bien sûr. Tu utilises les propriétés syntaxiques de Python et de ses setters pour réécrire l'affectation. Un lecteur peu au fait de ces subtilités verra dans listener.value = i une simple affectation classique alors qu'en réalité ça appelle une fonction de façon cachée, fonction que tu peux donc décorer à loisir pour y rajouter tous les traitements que tu veux. Certes ça répond à la problématique "comment checker une affectation" (parce que "changer de valeur" ça se traduit par "affecter une nouvelle valeur à la place de l'ancienne")... mais ça ne répond pas à la problématique que j'ai soulevée (et qui me semble intéressante) : quelles circonstances peuvent amener un évènement à faire modifier une variable sans que l'on ne puisse alors surveiller l'évènement au lieu de surveiller la variable ? Parce que je sens que si le PO ne peut pas répondre à cette question, cela pourrait signifier qu'il a mal perçu certains points de son projet.

    Dit autrement : quelle que soit la ligne du code où il est écrit cette fameuse affectation de cette fameuse variable, on pourra toujours y rajouter une instruction avant (ou après), instruction contenant le code (ici un callback) que l'on veut associer à cette affectation.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 539
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 539
    Par défaut
    pour info, il a trouvé (me semble-t-il) une réponse satisfaisante à sa demande sur https://openclassrooms.com/forum/sujet/tkinter-fe9ed

  11. #11
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Ah ben oui évidemment !!! Mais sa question là-bas n'a rien, mais alors rien du tout à voir avec celle d'ici.
    Là bas il veut partir de Tk, faire exécuter un programme externe dans une boucle de traitement de n éléments (n photos) et dans Tk afficher le traitement en cours (style "traitement photo 1", "traitement photo 2" etc). C'est totalement à l'ouest de "surveiller une variable" quoi !!!
    En fait on se trouve dans un cas typique de problème XY. Au lieu de partir sur "comment dans tk afficher le déroulé d'un traitement externe" il est parti sur des "callback sur variables etc" bref...
    Nom : projet.png
Affichages : 414
Taille : 15,6 Ko

    Et le plus triste c'est que son souci fait partie des soucis connus des GUI (comment mettre à jour une GUI lors de tâches externes) que Qt permet de résoudre via les Qthread. Certainement que Tk permet une solution analogue (à base là aussi de thread probablement)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  12. #12
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 323
    Par défaut
    Merci umfred

    Si je comprends (merci Caplande de nous avoir jamais donné le contexte), il voulait simplement faire une barre de progression (d'un traitement de photos)

    Passer a Tk est quand même extrême et des solutions dans un terminal existent. Si l'utilisation d'une interface graphique n'est pas un handicap pour le traitement, alors ok.

  13. #13
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Si l'utilisation d'une interface graphique n'est pas un handicap pour le traitement, alors ok
    Au départ il n'était pas question d'interface graphique, d'ailleurs sur l'autre forum il le précise. Qui puis est il indique se sentir obligé d'utiliser une IHM...

    Bref, le PO n'a jamais proposé de codes indiquant que l'une ou l'autre des solutions proposées ne correspondaient pas à ce qu'il souhaitait et surtout pourquoi ça ne correspondait pas, ce qui rend difficile la compréhension de son problème.

    C'est un problème XY peut-être, moi quand je vois pas de code, je me sens un peu baladé par les belles paroles du PO !

Discussions similaires

  1. Evénement sur le changement de valeur d'une variable
    Par kimcharlene dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 17/08/2012, 20h56
  2. Evenement sur changement d0une valeur d'une variable
    Par Destiny dans le forum Windows Forms
    Réponses: 2
    Dernier message: 09/04/2008, 09h28
  3. Réponses: 8
    Dernier message: 29/03/2007, 14h48
  4. [VB.NET]Test sur changement de valeur d'une variable
    Par shinji_rem dans le forum Windows Forms
    Réponses: 9
    Dernier message: 29/11/2006, 15h53
  5. Intercepter le changement de valeur d'une variable
    Par Captain_JS dans le forum C++Builder
    Réponses: 5
    Dernier message: 07/01/2005, 08h04

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