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 :

Communication entre classes [Python 2.X]


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 35
    Points : 19
    Points
    19
    Par défaut Communication entre classes
    Bonjour à tous,

    Suite à la création d'un logiciel de caisse, j'ai souhaité diviser mon programme en plusieurs classes.

    J'ai donc :
    - une Classe Application qui initialise le ticket et les produits,
    - une Classe Ticket qui initialise le numéro du ticket et affiche les produits du ticket,
    - et une Classe Produit qui doit récupérer ce numéro de ticket, pour y insérer les produits....


    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
     
    class Application(Frame):
            def __init__(self,master):
     
                    # Frame d'affichage du Ticket #
                    FrameT = Frame(master,width=200,height=200)
                    FrameT.pack()
                    FrameT.propagate(False)
     
                    Ticket(FrameT)
     
                    # Frame d'affichage des produits #
                    FrameP = Frame(master,width=200,height=200)
                    FrameP.pack()
                    FrameP.propagate(False)
     
                    Produits(FrameP)
     
    class Ticket(Frame):
            def __init__(self,master,*args):
     
                    # Si aucun numéro de ticket n'a été définie, je récupère le numéro MAX contenue dans la Table Tickets, et j'incrémente de 1
                    if args == (): 
                            nb = Mysqlrequests.NewTicket()  
                            numero = nb[0]
                            numero +=1
                    else:
                            numero = args[0]
     
                    self.LabelTicketN = Label(master,text="Ticket n° %s" % (numero))
                    self.LabelTicketN.pack()
     
                    ListProduits = Mysqlrequests.TicketProducts(numero) # Recup des produits du ticket
                    for p in ListProduits:
                            Pname = p[0]
                            self.LProduit = Label(master,text=Pname)
                            self.LProduit.pack()
     
    class Produits(Frame):
            def __init__(self,master):
                    Produits = ["pizza","frite","coca"] # en vrais les produits sont dans la BDD, mais pour l'exemple j'ai préféré utilisé une liste
                    for produit in Produits:
                            PButtons = Button(master,text=produit,fg='black',state='normal',command=lambda Pname=produit:self.ProduitAdd(Pname),width=20,height=3)
                            PButtons.pack()
     
            def ProduitAdd(self,Pname):
                    Mysqlrequests.ProductAdd(self.numero,Pname) Ajout du produit au ticket
     
    tk = Tk()
    app = Application(tk)
    tk.mainloop()
    Je ne sais pas du tout comment faire pour que la classe "Produit" récupère le numéro de ticket incrémenter par la classe "Ticket",
    et il faudrait que la classe produit puisse réinitialiser l'affichage des produits du ticket au moment de l'ajout d'un produit.

    Bref, j'ai beaucoup cherché sur le net et entre variable globale et instanciation d'objet, rien ne convient. je ne sais vraiment pas comment faire.

    Si quelqu'un à une idée, je suis preneur.

    Merci d'avance.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    J'ai l'impression que vous mélangez un peu tout dans votre tête.

    Ce dont vous avez besoin :

    * une classe Application qui comme son nom l'indique va représenter la totalité de votre application : c'est elle le chef d'orchestre de votre programme, c'est elle qui crée les tickets, gère les produits, dit ce qu'il faut afficher, où, quand et comment;

    * une classe Produit qui est une structure passive (qui n'a donc rien à voir avec de l'affichage) qui se contente de contenir des informations pour chaque produit individuellement : numéro identifiant unique, code produit, référence fabricant, référence vendeur, désignation / libellé, prix unitaire, quantité, conditions spéciales (soldes, remise, escompte, destockage, ...), prix final, taux de TVA selon produit, etc ;

    * une classe Ticket qui est une structure passive (qui n'a rien à voir avec de l'affichage) qui va gérer une liste de produits en tant que facture de caisse : numéro identifiant unique ticket, date/heure impression, référence commande client, mentions légales, etc ;

    En pratique, il faudrait aussi créer la classe CommandeClient, une structure passive (rien à voir avec de l'affichage non plus, il ne faut pas tout mélanger) qui gère la commande du client avant facturation et impression du ticket : n° identifiant unique, référence client, date/heure création, liste des produits commandés, éventuellement sous-total avant conditions spéciales, conditions spéciales (remise globale, escompte sur commande, etc), montant total commande, etc, etc... selon cahier des charges.

    Il faudra certainement envisager la conception de quelques autres classes encore...

    Déroulement des actions :

    * étape numéro 1 : la classe Application s'occupe d'initialiser l'affichage, de proposer à l'utilisateur une liste de produits à commander d'un côté et une liste (vierge au début) de produits commandés de l'autre côté.

    * l'utilisateur a la possibilité d'ajouter mais aussi d'enlever des produits commandés tant qu'il n'a pas validé définitivement sa commande.

    * c'est encore la classe Application qui fait le lien entre l'utilisateur et les composants du logiciel : c'est elle qui gère la liste des produits extraits de la BDD, les affiche dans un objet dédié, gère la liste de la commande, les boutons "ajouter produit", "enlever produit", "valider commande", "annuler commande", etc.

    Note : on pourra envisager un composant logiciel SaisieCommande pour s'occuper de cette tâche spécifique par délégation de rôle de la part de la classe Application, mais pour l'instant le mieux reste d'affecter cette tâche à la classe Application, c'est formateur.

    * une fois que l'utilisateur a validé sa commande, la classe Application propose un récapitulatif à confirmer avant paiement ou à modifier en cas de doute (dans ce cas, retour à la saisie commande, étape précédente).

    * une fois le récapitulatif validé, la classe Application gère la phase paiement du client (espèces, chèque, carte bancaire, mandat, lettre de change, etc).

    * une fois le paiement confirmé, la classe Application gère l'édition (impression) du ticket de caisse : ce n'est qu'à ce moment précis que l'on crée une instance de la classe Ticket avec les données qui vont bien avant d'envoyer le ticket à l'imprimante ;

    * une fois le ticket de caisse imprimé, la classe Application retourne à l'étape numéro 1 pour proposer une nouvelle commande à un nouveau client, et ainsi de suite en boucle.

    Une bonne analyse commence toujours par poser sur le papier qui doit faire quoi ?

    Croyez-vous que ce soit le rôle d'un produit de gérer de l'affichage ? Un produit, c'est un ensemble d'informations à gérer, rien de plus.

    Idem pour un ticket : c'est un ensemble d'informations à gérer. Pour son affichage, il y aura un autre objet TicketView spécialisé dans l'affichage qui s'occupera de représenter à l'écran ce que le ticket a dans le ventre.

    De même pour le passage à l'imprimante : c'est l'objet printer qui s'occupe d'imprimer l'objet ticket et non pas l'objet ticket qui s'occupe de discuter avec printer pour lui dire comment il aimerait que printer l'imprime.

    Chacun son métier : l'objet ticket facture une commande, résume les données de l'acte de vente et l'objet printer s'occupe d'imprimer des ensembles de données sur les indications d'un objet TicketPrinterView qui lui dit comment un ticket doit s'afficher en public.

    Voyez-vous mieux où se cache votre/vos erreurs d'analyse ?

    N'hésitez pas à prendre un crayon et un bloc-notes et à noter toutes les étapes du processus de vente : identification client, saisie commande, récapitulatif, paiement, création ticket de caisse, impression ticket de caisse, retour à l'étape 1, etc, puis à détailler ensuite chacune de ces étapes : que fait "identification client" dans le détail ? que fait "saisie commande" dans le détail ? etc, etc.

    Courage, la démarche est longue, mais si vous l'effectuez correctement, il n'y a aucune raison pour que vous n'y arriviez pas.

    @+.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 35
    Points : 19
    Points
    19
    Par défaut
    Ok,
    Merci pour ces informations très détaillés.

    Si on suit votre analyse, et si j'ai bien compris; la Classe "Application" contiendrait la partie "Graphique" du programme et les autres Classes la partie "Logique".

    C'est donc à la Classe "Application" d'instancier la class TicketView qui elle même affichera les informations de la Classe Ticket.
    Dans cette exemple, c'est donc bien la Classe Application qui s'occupera de "rafraîchir" la class "TicketView".

    c'est bien ça, j'ai bien compris ?

    Cependant, je ne sais pas trop comment faire, pour créer à la fois une classe définissant quelque chose et à la fois y accéder pour récupérer quelque chose depuis une autre Classe.

    Pour faire simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Ticket:
        def __init__(self,nb,produit,quant,prix):
            self.list = [nb,produit,quant,prix]
     
        def Getlist(self):
            return self.list
    Pour moi, le seul moyen d'accéder à la fonction "Getlist" de cette Classe est d'utiliser une instanciation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    list = Ticket()
    result = list.Getlist()
    Mais, ça ne peux pas marcher.

    Ou alors peut-être....:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Ticket:
        def __init__(self):
            pass
     
        def Add(self,nb,produit,quant,prix):
            self.list = [nb,produit,quant,prix]
     
        def Getlist(self):
            return self.list
    Mais c'est pas super propre...

  4. #4
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Évite d'utiliser des noms du langage pour ton propre usage. Donc ceci:
    est à bannir, utilise plutôt un nom qui dit de quoi il s'agit.
    D'autre part il faut préserver une référence aux objets que tu crées pour pouvoir les réutiliser.
    Ce qui veut dire que dans ta classe Application tu dois instancier la classe Ticket avec self, ensuite tu n'auras plus besoin de ton getter (je parle de la méthode Getlist()).
    Tu pourras faire simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    self.ticket = Ticket()
     
    # Et pour connaître le contenu du ticket
    products = self.ticket.list
    De nouveau même commentaire pour le nom, dans ta classe remplace le mot list par autre chose.

    Je vois aussi ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        def Add(self,nb,produit,quant,prix):
            self.list = [nb,produit,quant,prix]
    Tu sais que tu n'ajoutes pas un produit au ticket en faisant comme ça ? Tu remplaces le produit existant par le nouveau, c'est intentionnel ?

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par fabien493 Voir le message
    Ok,
    Merci pour ces informations très détaillés.

    Si on suit votre analyse, et si j'ai bien compris; la Classe "Application" contiendrait la partie "Graphique" du programme et les autres Classes la partie "Logique".
    Non, c'est la classe Application qui contient la "Logique" du programme : elle est le Modèle principal - voir concept MVC Modèle-Vue-Contrôleur http://fr.wikipedia.org/wiki/Mod%C3%...ontr%C3%B4leur

    C'est donc à la Classe "Application" d'instancier la class TicketView qui elle même affichera les informations de la Classe Ticket.
    Dans cette exemple, c'est donc bien la Classe Application qui s'occupera de "rafraîchir" la class "TicketView".

    c'est bien ça, j'ai bien compris ?
    La classe Application s'occupe d'instancier tout le monde : les objets d'affichage *View, les objets de structure (Ticket, Produit, CommandeClient, etc), la zone d'affichage elle-même (ici une fenêtre principale Tk()), etc.

    Une fois qu'elle a instancié tout ce petit monde, c'est encore elle qui va mettre tous ces composants en relation les uns avec les autres.

    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
    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
     
    import datetime
    from tkinter import *
     
    # exemple avec la classe Ticket
     
    def today ():
        return str(datetime.date.today())
    # end def
     
    class Ticket:
        def __init__ (self, **kw):
            # init membres de la classe
            self.identifiant = id(self)
            self.commande_client = kw.get("commande_client")
            self.date_impression = kw.get("date_impression") or today()
            self.offres_speciales = kw.get("offres_speciales")
            self.mentions_legales = kw.get("mentions_legales")
            # ...etc...
        # end def
    # end class Ticket
     
    class TicketView:
        DEFAULT_TEMPLATE = """\
    Ticket no. : {id_ticket}
    Commande no. : {id_commande}
    Client : {id_client}    date : {date_impression}
     
    {liste_produits}
     
    {offres_speciales}
     
    {mentions_legales}
    """
        def __init__ (self, **kw):
            # init membres de la classe
            self.ticket = kw.get("ticket")
            self.template = kw.get("template") or self.DEFAULT_TEMPLATE
        # end def
     
        def get_output (self):
            """
                ici, on fournit le résultat à afficher sous forme d'une
                chaîne de caractères qui pourra être remaniée par
                l'objet spécialisé affichage spécifique à l'application
                en cours;
            """
            # c'est du brut de décoffrage - il faut peaufiner bien sûr
            fields = dict(
                id_ticket=self.identifiant,
                id_commande=self.ticket.commande_client.identifiant,
                id_client=self.ticket.commande_client.client.identifiant,
                date_impression=self.ticket.date_impression,
                liste_produits=self.ticket.get_facture(formatter=str),
                offres_speciales=self.ticket.offres_speciales,
                mentions_legales=self.ticket.mentions_legales,
            )
            return str(self.template).format(**fields)
        # end def
    # end class TicketView
     
    class CommandeClient:
        def __init__ (self, **kw):
            # init membres de la classe
            self.identifiant = id(self)
            self.client = kw.get("client")
            self.date_commande = kw.get("date_commande") or today()
            self.liste_produits = list()
            # ...etc...
        # end def
    # end class CommandeClient
     
    class Client:
        def __init__ (self, **kw):
            # init membres de la classe
            self.identifiant = id(self)
            self.nom = kw.get("nom")
            self.prenom = kw.get("prenom")
            self.adresse = kw.get("adresse")
            self.code_postal = kw.get("code_postal")
            self.ville = kw.get("ville")
            # ...etc...
        # end def
    # end class Client
     
    class Application (Tk):
        def __init__ (self, **kw):
            # super class inits first /!\
            Tk.__init__(self)
            # maintenant, on peut instancier les principaux objets
            self.init_widgets(**kw)
        # end def
     
        def init_widgets (self, **kw):
            "on instancie les composants du logiciel ici"
            # un peu de bazar
            self.title("Exemple ticket de caisse")
            self.resizable(width=False, height=False)
            # ouvrir une connexion BDD
            # récupérer liste produits à vendre
            # etc
            pass
            # objets affichage
            self.view_produits = Canvas(
                self, bg="sky blue", width=200, height=300
            )
            self.view_commande = Canvas(
                self, bg="pale goldenrod", width=200, height=300
            )
            self.bouton_ajouter = Button(
                self, text="Ajouter >>", command=None,
            )
            self.bouton_enlever = Button(
                self, text="<< Enlever", command=None,
            )
            self.bouton_valider = Button(
                self, text="Valider\ncommande", command=None,
            )
            self.bouton_annuler = Button(
                self, text="Annuler\ncommande", command=None,
            )
            self.bouton_quitter = Button(
                self, text="Quitter\nl'application", command=self.quit,
            )
            # layout inits
            Label(
                self,
                text="Produits disponibles:"
            ).grid(row=0, column=0, padx=5, pady=5)
            self.view_produits.grid(
                row=1,
                column=0,
                rowspan=6,
                sticky=NW+SE,
                padx=5,
                pady=5,
            )
            Label(
                self,
                text="Commande client:"
            ).grid(row=0, column=2, padx=5, pady=5)
            self.view_commande.grid(
                row=1,
                column=2,
                rowspan=6,
                sticky=NS,
                padx=5,
                pady=5,
            )
            self.bouton_ajouter.grid(row=3, column=1, sticky=EW)
            self.bouton_enlever.grid(row=5, column=1, sticky=EW)
            self.bouton_annuler.grid(row=10, column=0, padx=5, pady=5)
            self.bouton_valider.grid(row=10, column=1, padx=5)
            self.bouton_quitter.grid(row=10, column=2, sticky=E, padx=5)
            self.rowconfigure(2, weight=1)
            self.rowconfigure(6, weight=1)
        # end def
     
        def run (self, **kw):
            "on lance l'application ici"
            # première étape du programme
            self.nouvelle_commande(**kw)
            # on lance la boucle principale Tkinter
            self.mainloop()
        # end def
     
        def nouvelle_commande (self, **kw):
            "on crée une nouvelle commande pour un nouveau client"
            # inits - exemples bidons
            self.client = Client(
                nom="Cavère",
                prenom="Nicole",
                adresse="Rue de la Grotte",
            )
            self.commande_client = CommandeClient(client=self.client)
            # saisie nouvelle commande
            self.saisir_commande()
        # end def
     
        def saisir_commande (self):
            "on gère ici la saisie / modification d'une commande"
            # RAZ affichages
            self.view_produits.delete(ALL)
            self.view_commande.delete(ALL)
            # on re-remplit la liste des produits disponibles
            self.remplir_liste_produits()
            # ...etc...
            pass
        # end def
     
        def remplir_liste_produits (self):
            "...etc...etc..."
            pass
        # end def
    # end class Application
     
    # module appelé en tant que script à exécuter ?
    if __name__ == "__main__":
        # on lance l'application
        Application().run()
    # end if
    @+.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 35
    Points : 19
    Points
    19
    Par défaut
    Bonjour à tous,

    Tu sais que tu n'ajoutes pas un produit au ticket en faisant comme ça ? Tu remplaces le produit existant par le nouveau, c'est intentionnel ?
    Il était 4h37 quand j'ai écrit ça, j'étais fatigué, promis la prochaine fois, j'utiliserais un "Dictionnaire"

    Merci encore pour toutes ces informations, surtout le concept MVC que j'ai trouvé super intéressant et très juste.

    Il y a une chose que je n'arrive pas à comprendre tarball69 :

    Dans la Class "TicketView", tu définis un Index "id_commande" qui a comme valeur "self.ticket.commande_client.identifiant" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fields = dict(
                id_ticket=self.identifiant,
                id_commande=self.ticket.commande_client.identifiant,
                ....
    Sauf que la variable self.ticket a comme valeur, la valeur de l'index "ticket" dans l'argument "**kw", de ce fait, comment la variable self.ticket peut avoir un ".commande_client." ?

    J'ai pas compris cette partie là, même en "brut de décoffrage"

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par fabien493 Voir le message
    Bonjour à tous,
    Il y a une chose que je n'arrive pas à comprendre tarball69 :

    Dans la Class "TicketView", tu définis un Index "id_commande" qui a comme valeur "self.ticket.commande_client.identifiant" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fields = dict(
                id_ticket=self.identifiant,
                id_commande=self.ticket.commande_client.identifiant,
                ....
    Sauf que la variable self.ticket a comme valeur, la valeur de l'index "ticket" dans l'argument "**kw", de ce fait, comment la variable self.ticket peut avoir un ".commande_client." ?

    J'ai pas compris cette partie là, même en "brut de décoffrage"
    Oui, c'est peut-être un raccourci éducatif un peu rapide : la classe TicketView va agir comme une sorte d'enveloppe (wrapper) pour la classe Ticket. Par conséquent, lorsqu'on va instancier la classe TicketView, il nous faudra l'initialiser avec un objet Ticket() pré-existant.

    Exemple 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
    24
    25
    26
    27
    28
    # à un moment du programme
    # on va trouver quelque chose comme ça
    # (dans la classe Application) :
     
        def afficher_ticket (self):
            """
                on affiche le ticket de caisse;
            """
            # on génère un nouveau ticket de caisse
            # à partir de la commande client actuelle;
            # pour simplifier, on initialise uniquement le paramètre
            # 'commande_client';
     
            _ticket = Ticket(commande_client=self.commande_en_cours)
     
            # ensuite, on crée un TicketView pour afficher à l'écran;
            # c'est un exemple pour simplifier et pour aider à la
            # compréhension des mécanismes en oeuvre;
            # pareil, ici on initialise uniquement le paramètre 'ticket'
            # pour simplifier;
     
            ticket_view = TicketView(ticket=_ticket)
     
            # exemple générique d'affichage en console
     
            print(ticket_view.get_output())
     
        # end def
    Donc dans la définition de TicketView :

    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
    class TicketView:
     
        # ...etc...
     
        def __init__ (self, **kw):
            # init membres de la classe
     
            # on attend un objet Ticket()
            # dans le paramètre 'ticket'
            # qui sera passé lors de l'instanciation de TicketView
            # e.g.
            # _ticket = Ticket(commande_client=self.commande_en_cours)
            # ticket_view = TicketView(ticket=_ticket)
     
            self.ticket = kw.get("ticket")
     
            self.template = kw.get("template") or self.DEFAULT_TEMPLATE
     
        # end def
    Idem lors de l'instanciation de la classe Ticket qui attend l'objet CommandeClient() en cours d'utilisation en paramètre 'commande_client' :

    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
    class Ticket:
        def __init__ (self, **kw):
            # init membres de la classe
            self.identifiant = id(self)
     
            # on attend un objet CommandeClient()
            # dans le paramètre 'commande_client'
            # qui sera passé lors de l'instanciation de Ticket
            # e.g.
            # _ticket = Ticket(command_client=self.commande_en_cours)
     
            self.commande_client = kw.get("commande_client")
     
            self.date_impression = kw.get("date_impression") or today()
            self.offres_speciales = kw.get("offres_speciales")
            self.mentions_legales = kw.get("mentions_legales")
            # ...etc...
        # end def
    # end class Ticket
    @+.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 35
    Points : 19
    Points
    19
    Par défaut
    Bonjour à tous,

    Je ne pensais pas qu'on pouvais instancier un objet avec un autre.
    Je trouve ça incroyable...

    En même temps quand VinsS à écrit :
    self.ticket = Ticket()

    # Et pour connaître le contenu du ticket
    products = self.ticket.list
    Cela aurais du me mettre "la puce à l'oreille"....(désolé VinsS j'ai n'ai pas fais attention).

    Encore une question qui me trotte dans la tête :

    La variable self.identifiant a comme valeur id(self). ça correspond à quoi exactement ? (On dirait une classe fantôme propre à python, qui retourne une valeur différente suivant ou on l'instancie )

    Edit: Je me demande quand même si instancier un objet avec un autre et récupérer les valeurs via des "get" est vraiment mieux que de les déclarer directement. Le traitement des informations n'est pas plus longs ?

    Amicalement,

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par fabien493 Voir le message
    Bonjour à tous,

    Je ne pensais pas qu'on pouvais instancier un objet avec un autre.
    Je trouve ça incroyable...
    Et pourquoi pas ?

    L'instanciation d'une classe en objet est juste un mécanisme qui permet à une structure (une classe) d'exister au travers d'une copie (un objet) que l'on peut ensuite personnaliser à volonté.

    Un mécanisme reste un mécanisme, peu importe où on l'utilise.

    La variable self.identifiant a comme valeur id(self). ça correspond à quoi exactement ? (On dirait une classe fantôme propre à python, qui retourne une valeur différente suivant ou on l'instancie )
    Non non c'est juste une fonction Python qui retourne un identifiant unique pour chaque objet créé (hashage).

    Voir ici : https://docs.python.org/2/library/functions.html#id

    Y a (toujours) pas de magie incantatoire avec Python.

    Edit: Je me demande quand même si instancier un objet avec un autre et récupérer les valeurs via des "get" est vraiment mieux que de les déclarer directement. Le traitement des informations n'est pas plus longs ?

    Amicalement,
    Déclarer directement ? Vous pourriez préciser ? Je ne comprends pas ?

    @+.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 35
    Points : 19
    Points
    19
    Par défaut
    Déclarer directement ? Vous pourriez préciser ? Je ne comprends pas ?
    Entre une classe qui assigne des variables via des gets:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class GetClient:
            def __init__ (self, **kw):
                    nom = kw.get("nom")
                    prenom = kw.get("prenom")
                    adresse = kw.get("adresse")
    et une Classe ou les variables sont déjà déclarés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class VarClient:
            def __init__ (self, nom, prenom, adresse):
                    ....
    Les exemples ci-dessus ne déclares que 3 variables, mais pour une centaine de variables, je me demande si le temps de traitement du get n'est pas plus longs ?

  11. #11
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par fabien493 Voir le message
    Les exemples ci-dessus ne déclares que 3 variables, mais pour une centaine de variables, je me demande si le temps de traitement du get n'est pas plus longs ?
    Hum 100 paramètres => il y a forcément un souci d'organisation.

    En temps normal, on dépasse rarement la vingtaine de paramètres.

    Pour la différence entre paramètres déclarés (a, b, c, ...) et liste variable de paramètres nommés (**kw), c'est une question d'approche.

    Dans le cas des paramètres déclarés (a, b, c, ...) on veut des paramètres obligatoires (Python va gueuler si on ne passe pas ce qui est attendu). C'est contraignant, à chaque objet, on est obligé de passer tous les paramètres demandés.

    A contrario, avec les paramètres nommés, on peut ne passer que les paramètres qui nous intéressent à un moment donné.

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    client1 = Client(nom="Cavère", prenom="Nicole")
    client2 = Client(nom="Zette", prenom="José", age=50)
    client3 = Client(nom="Dupont", adresse="Rue du pont")
    ...etc...
    C'est une gestion plus souple des paramètres.

    Bien entendu, on peut rendre certains paramètres obligatoires et d'autres facultatifs.

    Pour le cas de la classe Client, on peut décider qu'un objet client ne pourra être créé que si l'on fournit au moins un nom et un prénom, le reste des paramètres n'étant pas indispensable au moment précis de la création de l'objet : on les déclarera après coup, ce n'est pas si important.

    Dans ce cas, on écrira :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Client:
        def __init__ (self, nom, prenom, **kw):
            self.nom = nom
            self.prenom = prenom
            self.age = kw.get("age")
            ...etc...

    @+.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 35
    Points : 19
    Points
    19
    Par défaut
    J'avais bien compris cette partie là.

    Ma question portait plus sur les temps de traitements d'une Classe, entre une variable passé en paramètre, et une recherche sur une liste variable de paramètres. Mais ça ne doit pas être perceptible.

    Bref, je pense que le sujet principal a été parfaitement approfondie, je vais pouvoir réécrire mon programme en suivant vos conseils. Je met ce Post en "résolu".

    Merci infiniment à tous.

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

Discussions similaires

  1. Communication entre classes
    Par sunshine33 dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 03/02/2010, 21h04
  2. communication entre classes
    Par milomar dans le forum C++
    Réponses: 6
    Dernier message: 02/03/2008, 11h59
  3. Communication entre classes
    Par matteli dans le forum C++
    Réponses: 6
    Dernier message: 25/02/2008, 11h45
  4. Problème de communication entre classe
    Par FabaCoeur dans le forum Général Java
    Réponses: 4
    Dernier message: 22/01/2008, 13h50
  5. [c#] probléme de communication entre classe
    Par OpenGG dans le forum C#
    Réponses: 1
    Dernier message: 24/09/2006, 21h54

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