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 :

Inheritance into composition


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Chômeur professionnel
    Inscrit en
    Novembre 2020
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Algérie

    Informations professionnelles :
    Activité : Chômeur professionnel

    Informations forums :
    Inscription : Novembre 2020
    Messages : 122
    Par défaut Inheritance into composition
    Wesh les gars,

    Comme l'indique le titre, je veux transformer une inheritance en composition. Je sais que mon problème est la ligne "self.agency = All_Clients.__init__(agency)", mais aucune idée comment récupérer l'attribut de l'autre classe quand il s'agit d'une composition.

    ça c'est la version inheritance
    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
    class Client:
        def __init__(self, agency):
            self.agency = agency
        def printout(self):
            return f'{self.agency}'
     
    class Buying_Client(Client):
        def __init__(self, fullname, amount, agency):
            super().__init__(agency)
            self.fullname = fullname
            self.amount = amount
        def printout(self):
            parent = super().printout()
            return f'{self.fullname}, {self.amount}, {parent}'
     
    variable_1 = Buying_Client("John DOE", "$100", "NYC")
    variable_2 = Buying_Client.printout(variable_1)
    print(variable_2)
    Et ça c'est une tentative de composition

    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
    class All_Clients(object):
        def __init__(self, agency):
            self.agency = agency
        def printout(self):
            return f'{self.agency}'
     
    class Buying_Client(object):
        def __init__(self, fullname, amount, agency):
            self.fullname = fullname
            self.amount = amount
            self.agency = All_Clients.__init__(agency)
        def printout(self):
            other_class = All_Clients.printout()
            return f'{self.fullname}, {self.amount}, {other_class}'
     
    variable_1 = Buying_Client("John DOE", "$100", "NYC")
    variable_2 = Buying_Client.printout(variable_1)
    print(variable_2)

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    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 833
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Yuseph Voir le message
    Wesh les gars,
    Wesh

    Citation Envoyé par Yuseph Voir le message
    mais aucune idée comment récupérer l'attribut de l'autre classe quand il s'agit d'une composition.
    Tu ne récupères pas l'attribut d'une autre classe, mais l'attribut d'une instance de l'autre classe.
    Si tu écris toto=Client("xxx"), tu peux alors récupérer l'attribut "agency" de cette façon: print(toto.agency). Ben c'est exactement la même chose quand ça se passe dans une autre classe. Faut juste que tu crées l'instance.
    Code python : 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
    class All_Clients(object):
    	def __init__(self, agency):
    		self.agency = agency
    	def printout(self):
    		return f'{self.agency}'
     
    class Buying_Client(object):
    	def __init__(self, fullname, amount, agency):
    		self.fullname = fullname
    		self.amount = amount
    		self.agency = All_Clients(agency)
    	def printout(self):
    		return f'{self.fullname}, {self.amount}, {self.agency.printout()}'
     
    variable_1 = Buying_Client("John DOE", "$100", "NYC")
    print(variable_1.printout())

    Citation Envoyé par Yuseph Voir le message
    variable_2 = Buying_Client.printout(variable_1)
    Abandonne cette syntaxe idiote. Tu penses faire genre mais ça fait juste type qui connait pas la POO. Et que se passera-t-il si par erreur tu appelles autre_classe.printout(variable1)???

    variable_2 = variable_1.printout(). C'est la syntaxe standard d'un appel de méthode en POO.
    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
    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 Yuseph Voir le message
    mais aucune idée comment récupérer l'attribut de l'autre classe quand il s'agit d'une composition.
    Normalement, vous savez déjà le faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> liste = []
    >>> liste.append(1)
    >>> liste
    [1]
    >>>
    On crée une liste assignée à la variable liste. On lui ajoute l'entier 1 en accédant à son attribut "append" pour l'appeler en tant que "méthode" avec 1 en paramètre. On vérifie que ça a marché.

    Avec les classes, on aurait des attributs (self.liste) à la place de variables (liste) sur la partie gauche et la même chose côté droit. Ca se ressemble beaucoup...

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

  4. #4
    Membre actif
    Homme Profil pro
    Chômeur professionnel
    Inscrit en
    Novembre 2020
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Algérie

    Informations professionnelles :
    Activité : Chômeur professionnel

    Informations forums :
    Inscription : Novembre 2020
    Messages : 122
    Par défaut
    eh bien purée

    il fallait le savoir.

    Moi je tapais self.agency ça me renvoyait les meta données

  5. #5
    Membre actif
    Homme Profil pro
    Chômeur professionnel
    Inscrit en
    Novembre 2020
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Algérie

    Informations professionnelles :
    Activité : Chômeur professionnel

    Informations forums :
    Inscription : Novembre 2020
    Messages : 122
    Par défaut
    Bon j'ai essayé ça c'est plus simple pour moi

    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
     
    class All_Clients(object):
        def __init__(self, agency):
            self.agency = agency
        def printout(self):
            return f'{self.agency}'
    class Buying_Client(object):
        def __init__(self, fullname, amount, agency):
            self.fullname = fullname
            self.amount = amount
            self.agency = All_Clients(agency)
        def printout(self):
            all_clients = self.agency.printout()
            return f'{self.fullname}, {self.amount}, {all_clients}'
    variable_1 = Buying_Client("John DOE", "$100", "NYC")
    print(variable_1.printout())
    Mais je ne pige pas pourquoi je suis obligé de mettre self.agency.printout() au lieu de All_Clients.printout().
    Bon l'essentiel c'est que ça marche

  6. #6
    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 Yuseph Voir le message
    Mais je ne pige pas pourquoi je suis obligé de mettre self.agency.printout() au lieu de All_Clients.printout()
    self.agency.printout() est l'appel de la méthode printout de l'objet associé à l'attribut self.agency.
    All_Clients.printout() est l'appel de la fonction printout de la classe All_Clients (qui va planter car elle attend un argument...)
    Si self.agency est un All_Clients, l'appel All_Clients.printout(self.agency) devrait fonctionner...

    Comprendre comment coder ce que vous voulez, ça vous y êtes obligé.

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

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    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 833
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Yuseph Voir le message
    self.agency.printout()

    il fallait le savoir.
    self.agency étant une instance de l'objet "All_Clients" tu as alors le droit d'appeler ses méthodes publiques si tu veux les utiliser. Tu es en effet censé le savoir, c'est la base de la POO.

    Citation Envoyé par Yuseph Voir le message
    Bon j'ai essayé ça c'est plus simple pour moi

    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 All_Clients(object):
        def __init__(self, agency):
            self.agency = agency
        def printout(self):
            return f'{self.agency}'
    class Buying_Client(object):
        def __init__(self, fullname, amount, agency):
            self.fullname = fullname
            self.amount = amount
            self.agency = All_Clients(agency)
        def printout(self):
            all_clients = self.agency.printout()
            return f'{self.fullname}, {self.amount}, {all_clients}'
    variable_1 = Buying_Client("John DOE", "$100", "NYC")
    print(variable_1.printout())
    Ouais enfin tu remarqueras qu'il n'y a aucune différence avec le code que j'ai écrit. Enfin si... tu utilises une variable intermédiaire pour stocker le retour du self.agency.printout(), variable que tu utilises ensuite juste en dessous (et que tu n'utilises ensuite plus ce qui donne un sérieux doute sur son utilité réelle )

    Citation Envoyé par Yuseph Voir le message
    Mais jpige pas pourquoi jsuis obligé de mettre self.agency.printout() au lieu de All_Clients.printout()
    Si printout() était une méthode statique de classe oui tu pourrais mais pas quand tu appelles une méthode d'instance. Là tu dois spécifier de quelle instance il s'agit.
    Exemple:
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class cercle():
    	def __init__(self, rayon): self.r=rayon
    	def surface(self): return 3.14 * self.r**2
     
    toto=cercle(5)
    titi=cercle(10)
    Maintenant je veux la surface d'un cercle, je suis bien obligé de dire duquel...


    Citation Envoyé par Yuseph Voir le message
    Bon l'essentiel c'est que ça marche
    Non, l'essentiel c'est que tu comprennes pour pouvoir ensuite en déduire comment faire des choses plus complexes. Sinon pourquoi on s'embêterait à t'expliquer?
    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
    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
    salut

    1) premier point, arrete d'inventer des noms qui n'ont aucun rapport logique avec la variable/méthode/classe

    Soit tu ne comprends rien à ce que tu tentes de faire, soit tu te forces à compliquer les choses (la poo est si simple )
    Peut-être que tu ne maitrises pas l'anglais ? alors utilise le francais !

    class All_Clients oui, tous les clients on une Agence ! mais il faut noter que aussi tous les clients ont un "nom", donc si on suis ta logique pourquoi ne pas nommer l'attribut "fullname" aussi all_clients
    C'est vrai qu'il est trop difficile d'imaginer une classe qui se nomme "Agency" ...

    Buying_Client.printout() méthode qui ne fait pas ce qu'indique son nom
    Je t'ai déjà dit dans un autre sujet que cette méthode n'est qu'un bricolage ! existe un système intégré dans Object pour faire le même chose, mais je suppose qu'il est plus gratifiant de tenter de faire mieux que les inventeurs de python ? Et cela ammène une fausse complexité à l'objet qui peut-être gratifiant.

    2) J'ai peur que ton livre soit plutôt bon pour la poubelle
    - me semble, dans un sujet précédent, que ton printout() vienne de lui ? (premier chapitre poo ok, ensuite ...)
    - class All_Clients(object): ancienne notation, aujourd'hui on n'indique pas l'héritage si il vient de object

    3) composition
    C'est une notion qui n'a pratiquement pas de valeur en python puisque tout est objet. La composition c'est simplement mettre un objet dans un objet. Donc ce que tu as vu dans ton tout premier cours python !!!!
    # avec une larme d'english pour te faire plaisir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Client:
        def __init(self, nom):
            self.name = nom
    c'est de la composition ! l'attibut self.name est un objet, donc ton exemple devrait être simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class Agence ...
     
    class Client:
        def __init(self, nom, agence):
            self.name = nom
            self.agency = agence
     
    papa = Client("mon papa", Agence("paris"))
    Et puisque papa.agency est une instance de la classe Agence, tu peux utiliser toutes les méthodes de papa.agency (comme celle de papa.name) !!!!!!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    papa.agency.getpays()
    papa.name.strip()
    ...
    Je le répète, c'est le premier cours oop, les objets en python utilisent toujours la composition

    -------------

    De plus héritage et composition, ce sont 2 notions qu'il ne faut pas opposer mais elle se completent. Par exemple, si je reprends mon code précédent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Agence ...
    class AgenceFr(Agence) ...
    class AgenceEn(Agence) ...
     
    class Client:
        def __init(self, nom: str, agence: Agence):
            self.name = nom
            self.agency = agence
     
    papa = Client("Paul", AgenceFr("paris"))
    maman = Client("Paulette", AgenceEn("Londres"))

Discussions similaires

  1. Réponses: 2
    Dernier message: 05/11/2009, 11h26
  2. Insert Into + Date
    Par BoeufBrocoli dans le forum SQL
    Réponses: 10
    Dernier message: 13/08/2003, 11h23
  3. [WSAD] Composition visuelle d'une applet
    Par schum11 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 09/04/2003, 16h19

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