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 :

passation de paramètres d'une méthode à une autre


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Août 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 88
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Août 2009
    Messages : 39
    Par défaut passation de paramètres d'une méthode à une autre
    Dans la fonction start du programme suivant je crée une variable time.time() que j'ai besoin de transmettre à la fonction stop
    Mais ces 2 fonctions sont lancées par un clic sur un bouton : <command = self.start> <command = self.stop>
    Ces 2 commandes n'ont pas la possibilité de transmettre des variables
    J'ai donc trouvé une solution qui n'est pas satisfaisante, je déclare dans fonction start :< self.debut = time.time>
    que je peux utiliser dans la fonction stop
    self.debut n'est même pas déclaré dans <créer_données> et bizarrement cela fonctionne
    pouvez vous me conseiller une solution correcte
    voici le programme :
    je vous remercie de votre réponse

    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
     
    from tkinter import *
    import tkinter as tk
    from random import randrange
    import time
     
    class Application(Tk) :    # on peut aussi utiliser <tk.Tk>     
        def __init__(self,x=20, y=20, r=5) :
            Tk.__init__(self)
            self.x = x
            self.y = y
            self.r = r        
            self.creer_donnees()
            self.creer_widgets()
     
        def creer_donnees(self ) :        
            self.delai =0.01
            self.flag = 0  #initialisé à arrêt
            self.cr = 0        
     
        def creer_widgets(self) :
            self.can = Canvas(self, height = 200, width = 750, bg = 'green')
            self.can.grid(row = 0,column = 0)
            self.balle = self.can.create_oval(self.x-self.r,self.y-self.r, self.x+self.r,
                                              self.y+self.r, fill  = 'red')
                #self.start sans () attend l'évènement et non self.start() qui lance la fonction
                #self.start ne peut comporter de paramètres d'ou la création de <start> qui lance <depl>
            self.bt = Button(self, text = 'start', bg = 'yellow', command = self.start)
            self.bt.grid(row =1, column = 0)
            self.bt1 = Button(self, text = 'Pause',  bg = 'light green', command = self.stop)
            self.bt1.grid(row =1, column = 1)
     
        def depl(self,x,y,r,cr) : #x,y,r sont alors dissociées des valeurs initiales
            x= x+1             #on peut les faire évoluer
            y =y +0.25      
            self.can.coords(self.balle,(x-r),(y-r),(x+r), (y+r))        
            self.can.update()    # instruction nécessaire pour mettre à jour can et donc l'avancement     
            if self.flag >0 :
                cr+=1
                time.sleep(self.delai)  #utilisation de sleep car self.after ne fonctionne pas
                                        #self.after(self.delai, self.depl(x,y,r))
                #arguments passés sans self deviennent des variables de méthodes modifiables        
                self.depl(x,y,r,cr)
     
        def start(self) :   # appelle les variables de classe
            self.flag = 1     #marche
            """on définit ici <self.debut> permet d'être transmis à  <stop>"""
            self.debut = time.time() 
            self.depl(self.x,self.y,self.r, self.cr)  # et les transmets à self.depl
     
        def stop(self) :        
            self.flag = 0
            fin = time.time()        
            elapsed = fin - self.debut
            elap = round(elapsed,2)
            print('C/ Temps d\'exécution :',elap, 'sec')
     
    if __name__ ==  '__main__' :  
        app = Application(0,10,12)   # instanciation de l'objet Application
        app.geometry('800x250')  
        app.mainloop()

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Bonjour à toi aussi
    Citation Envoyé par Cerisier Voir le message
    Dans la fonction start du programme suivant je crée une variable time.time() que j'ai besoin de transmettre à la fonction stop
    Mais ces 2 fonctions sont lancées par un clic sur un bouton : <command = self.start> <command = self.stop>
    Ces 2 commandes n'ont pas la possibilité de transmettre des variables
    Oui, c'est le principe des callbaks => ce n'est pas toi qui appelle start() ou stop() mais tk et tk les appelle d'une façon précise que tu ne peux pas changer.

    Citation Envoyé par Cerisier Voir le message
    J'ai donc trouvé une solution qui n'est pas satisfaisante, je déclare dans fonction start :< self.debut = time.time>
    que je peux utiliser dans la fonction stop
    Et pourquoi ce n'est pas satisfaisant ?

    Citation Envoyé par Cerisier Voir le message
    self.debut n'est même pas déclaré dans <créer_données> et bizarrement cela fonctionne
    Il suffit qu'il soit créé avant d'être utilisé et ça fonctionnera.

    Citation Envoyé par Cerisier Voir le message
    pouvez vous me conseiller une solution correcte
    A quel problème puisque ça fonctionne ?
    Le seul truc que je rajouterais moi, c'est de créer "debut" dans le __init__ pour être sûr qu'il existe dans toutes les configurations, et étant donné que c'est un attribut interne (donc privé) je le nommerais "__debut". Et si vraiment tu veux verrouiller le truc, tu peux le mettre dans l'attribut __slots__.
    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]

  3. #3
    Membre averti
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Août 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 88
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Août 2009
    Messages : 39
    Par défaut Merci pour la réponse et le lien
    Citation Envoyé par Sve@r Voir le message
    Bonjour à toi aussi

    Oui, c'est le principe des callbaks => ce n'est pas toi qui appelle start() ou stop() mais tk et tk les appelle d'une façon précise que tu ne peux pas changer.


    Et pourquoi ce n'est pas satisfaisant ?


    Il suffit qu'il soit créé avant d'être utilisé et ça fonctionnera.


    A quel problème puisque ça fonctionne ?
    Le seul truc que je rajouterais moi, c'est de créer "debut" dans le __init__ pour être sûr qu'il existe dans toutes les configurations, et étant donné que c'est un attribut interne (donc privé) je le nommerais "__debut". Et si vraiment tu veux verrouiller le truc, tu peux le mettre dans l'attribut __slots__.
    dans ce document <python-de-zero> je trouve des explications que je ne trouve pas ailleurs et qui clarifient la compréhension,
    il faut dire que ma formation de base en informatique remonte à 55 ans avec l'assembleur et le Cobol, forcément ça grince parfois, même souvent

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Cerisier Voir le message
    dans ce document <python-de-zero> je trouve des explications que je ne trouve pas ailleurs et qui clarifient la compréhension,
    C'était le but. Toutefois les explications que j'y ai mises je les ai forcément trouvées quelque part
    La page "remerciements" contient un site nommé "sam et max" décrivant extrèmement bien certains mécanismes Python. Ce site m'a vraiment beaucoup aidé à comprendre les choses. Dommage, il n'est plus actif (toujours présent mais plus mis à jour).
    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]

  5. #5
    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,

    Citation Envoyé par Cerisier Voir le message
    #utilisation de sleep car self.after ne fonctionne pas
    #self.after(self.delai, self.depl(x,y,r))

    La question cachée dans les commentaires du code...
    Avec .after, on écrira self.after(self.delai, self.depl, x,y,r) - pour passer des paramètres.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre averti
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Août 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 88
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Août 2009
    Messages : 39
    Par défaut Merci
    j'ai même eu une réponse à une question que je ne posais pas
    vous êtes très sympa de prendre du temps pour des inconnus
    je pensais, donc à tort, qu'on ne pouvait pas définir un attribut d'instance dans une méthode

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Cerisier Voir le message
    vous êtes très sympa de prendre du temps pour des inconnus
    On aime à faire progresser le niveau global, cela nous fait progresser nous aussi. Et peut-être que demain tu seras un crack dans tel domaine et que c'est moi qui aurait besoin d'aide. Ou un autre et toi tu l'aideras de la même façon et ainsi tout le monde y gagne(ra).

    Citation Envoyé par Cerisier Voir le message
    je pensais, donc à tort, qu'on ne pouvait pas définir un attribut d'instance dans une méthode
    C'est en effet tout à fait possible mais pas vraiment du tout conseillé. Si la méthode n'est pas appelée, ou appelée après une autre qui, elle, utilise ledit attribut, ça plante.
    Donc on prend l'habitude de les mettre dans le __init__ (qui se trouve être aussi une méthode donc si ça marche pour la méthode "__init__", il n'y a aucune raison que ce soit refusé dans une autre ).
    C'est même en plus possible de définir un attribut d'instance depuis l'extérieur même de la classe mais là c'est franchement la porte ouverte au bug direct (2 instances différentes pouvant alors ne pas avoir les mêmes attributs donc on ne peut plus uniformiser les actions et c'est le crash à plus ou moins long terme). C'est là que le __slots__ entre en jeu car il sert de verrou. On lui donne la liste des attributs autorisés et il empêche de créer un attribut qui n'y est pas. Je l'ai mis dans tous mes objets.

    Mais effectivement si Python offrait un outil équivalent permettant de bloquer la création d'attributs dans une méthode autre que __init__ j'apprécierais moi aussi grandement...
    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]

  8. #8
    Invité
    Invité(e)
    Par défaut
    Salut !

    Ces 2 commandes n'ont pas la possibilité de transmettre des variables
    Command et lambda : https://www.tutorialspoint.com/tkint...mbda-in-python
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Button(root, text="Bouton n° 1" ,command= lambda: ma_fonction("Bouton n° 1"))
    Correcte ?

  9. #9
    Membre Expert
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 923
    Billets dans le blog
    8
    Par défaut
    Bonjour,
    Citation Envoyé par LeNarvalo Voir le message
    Salut !


    Command et lambda : https://www.tutorialspoint.com/tkint...mbda-in-python
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Button(root, text="Bouton n° 1" ,command= lambda: ma_fonction("Bouton n° 1"))
    Correcte ?
    Oui.
    On peut aussi utiliser partial() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #from functools import partial
    Button(root, text="Bouton n° 1" ,command=partial(ma_fonction, "Bouton n° 1"))

  10. #10
    Membre averti
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Août 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 88
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Août 2009
    Messages : 39
    Par défaut Je ne comprends pas la syntaxe
    Citation Envoyé par wiztricks Voir le message
    Salut,




    La question cachée dans les commentaires du code...
    Avec .after, on écrira self.after(self.delai, self.depl, x,y,r) - pour passer des paramètres.

    - W
    Je reprends avec beaucoup de retard votre réponse
    Effectivement en utilisant <self.depl, x,y,r> ça marche et je vous en remercie
    Mais je ne comprends pas
    dans la fonction <start> j'utilise bien <self.depl(self.x,self.y,self.r, self.cr)>
    pourquoi je dois utiliser <self.depl, x,y,r> dans l'after
    <self.depl> ressemble à une syntaxe de callback
    Merci pour vos explications

  11. #11
    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
    Citation Envoyé par Cerisier Voir le message
    Mais je ne comprends pas
    Dans la méthode start, la fonction est appelée (immédiatement).
    Dans la logique "after", on passe une fonction à appeler plus tard avec son tas de paramètres.

    Quelque part, la syntaxe doit rendre compte de la différence.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Réponses: 17
    Dernier message: 21/08/2014, 15h21
  2. Passage de paramétre dans une autre page
    Par olivier94 dans le forum Langage
    Réponses: 8
    Dernier message: 08/03/2007, 11h21
  3. [Tableaux] Passer paramètre sur une autre page
    Par lafmart dans le forum Langage
    Réponses: 1
    Dernier message: 04/02/2007, 16h29
  4. Réponses: 7
    Dernier message: 06/05/2006, 15h06
  5. [VB]Passage de Fonction en paramètre (d'une autre fonction)
    Par Australia dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 21/03/2006, 18h55

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