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 :

problème d'héritage python 2.6


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 40
    Points : 23
    Points
    23
    Par défaut problème d'héritage python 2.6
    Bonjour,
    J'ai une classe mère (classe_mere) qui contient 2 fonctions membres (fonction_publique et __fontion_privee), la fonction fonction_publique fait appel à __fontion_privee:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class classe_mere(object):
                  def fonction_publique():
                       ...
                       self.__fontion_privee("chose")
     
                  def __fontion_privee(element):
                       ...
    Maintenant j'ai une classe fille (classe_fille) héritant de la classe mère, celle-ci comporte des modifications importantes de la __fonction_privee, mais 'aucune' pour la fonction_publique. Est-il possible de ne pas faire un 'copié/collé' de la fonction_publique de la classe mère vers la classe fille, en d'autre terme, comment faire pour que la fonction membre fonction_publique de la classe fille fasse référence à la nouvelle fonction membre __fonction_privee de la classe fille et non pas à la __fonction_privee de la classe mère?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class classe_fille(classe_mere):
                  def __fontion_privee(element):
                       #Nouveau code
                       ...
    Merci infiniment!!

    PS: sinon je vois une autre solution: casser la fonction_publique en trois: une faisant les traitements avant appel de la __fonction_privee, la __fonction_privee, une faisant les traitements après la __fonction_privee et une dernière fonction appelant les trois.... je trouve ça très laid.. y-a-t-il une solution élégante?

  2. #2
    Expert éminent

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

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

    D'après l'exemple que tu donnes, la classe fille n'hérite pas de la classe mere, ni de rien d'autre d'ailleurs.

    Est-ce que cet exemple répond à tes questions:
    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
     
    # -*- coding: utf-8 -*-
     
    class Main(object):
        def _public(self):
            self.__private('Main')
     
        def __private(self, val):
            print 'class: %s' %val
     
    class Fille(Main):
        def get_class_name(self):
            self.__private('Fille')
     
        def __private(self, val):
            print 'class: %s' %val
     
    m = Main()
    f = Fille()
     
    m._public()
    f.get_class_name()

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 40
    Points : 23
    Points
    23
    Par défaut
    Bonjour, et merci beucoup pour votre réponse.
    En effet mon exemple n'était pas très précis, j'ai un peu modifier, et en voici un bien plus précis:
    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
     
    # -*- coding: utf-8 -*-
     
    class Main(object):
        def public(self):
            text = self.__private(self)
            print("Je suis %s" %text)
     
        def __private(self, val):
            return "la fonction private de Main"
     
    class Fille(Main):
        def public(self):
            Main.public(self)
     
        def __private(self, val):
            return "la fonction private de Fille"
     
    m = Main()
    f = Fille()
     
    m.public()
    f.public()
    Résultat:
    Je suis la fonction private de Main
    Je suis la fonction private de Main

    Résultat voulu:
    Je suis la fonction private de Main
    Je suis la fonction private de Fille

  4. #4
    Expert éminent

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 302
    Points : 6 782
    Points
    6 782
    Par défaut
    Le résultat est conforme à ton code.

    Relis le mien.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 40
    Points : 23
    Points
    23
    Par défaut
    En effet le résultat est bien conforme à ce que j'ai écris, je le sais bien mais je cherche à le modifier afin obtenir l'autre résultat.

    En relisant ton code, j'avoue ne pas comprendre le '_' devant 'public' et en fait tu définies une nouvelle fonction "get_class_name" équivalente à '_public' or dans mon cas je veux éviter de faire cette nouvelle fonction et réutiliser '_public': l'idéal serai de "récupérer" la fonction '_public' afin qu'elle fasse référence à la fonction '__private' de la fonction fille et pas de la fonction 'Main'

  6. #6
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 180
    Points : 321
    Points
    321
    Par défaut
    Bonjour,

    Aie ! Il est vrai qu'au début programmer en orienté objet demande quelques efforts.

    Cependant cela en vaut vraiment la peine.

    Quelque chose m'interpelle dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class Main(object):
        def public(self):
            text = self.__private(self)  # Et pourquoi pas text=self.__private() ?
            print("Je suis %s" %text)
    Je pense que tes ennuis viennent de cette fameuse ligne text = ...

    La preuve, le code suivant qui date de l'époque où j'apprenais le Python et qui
    fonctionne :
    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 Mother(object):
        def __init__(self):
            self.a = 2
        def _private(self):
            return self.a
        def public(self):
            print(self._private())
     
    class Child(Mother):
        def __init__(self):
            Mother.__init__(self)
        def _private(self):
            return self.a*100

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 435
    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 435
    Points : 37 020
    Points
    37 020
    Par défaut
    Citation Envoyé par KR_Prog Voir le message
    Maintenant j'ai une classe fille (classe_fille) héritant de la classe mère, celle-ci comporte des modifications importantes de la __fonction_privee, mais 'aucune' pour la fonction_publique.
    Si une méthode est "privée", elle n'est visible que par la classe dans laquelle elle est définie. Les méthodes des autres classes (éventuellement s/classes) n'y ont pas accès (enfin Python n'est pas C++, et on pourra passer par derrière).

    Si vous voulez que les s/classes puissent redéfinir la méthode et qu'elle puisse être appelée, il faudrait que ce soit une méthode "publique" ou "protégée".
    Avec Python, "public" ou "protégé" n'est que convention (alors que "privé" modifie le chemin d'accès).
    - W

  8. #8
    Expert éminent

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 302
    Points : 6 782
    Points
    6 782
    Par défaut
    Il faut un GPS pour suivre tes explications.

    Le get_class_name() ne sert qu'à la démonstration. Oublions-le.

    Par contre, lorsque tu fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        def public(self):
            Main.public(self)
    avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        def public(self):
            text = self.__private(self)
            print("Je suis %s" %text)
    Il est normal que tu aies le résultat de Main.__private() et pas normal que tu attendes le résultat de Fille.__private().

    En général on évite ce genre de construction d'ailleurs.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 40
    Points : 23
    Points
    23
    Par défaut [Résolu] Problème d'héritage python 2.6
    Merci beaucoup!!
    En effet j'ai fait plusieurs erreurs, ayant fait du C++ en OO il y a quelque temps j'ai juste besoin de me rafraichir la mémoire et m'adapter à l'OO en python. En effet je me suis fait bloqué par la fonction privée, j'aurai due la déclarée protégée!
    Et en effet les fonctions protégées n'existe pas en python de ce que j'ai lu:
    http://docs.python.org/2/reference/l...of-identifiers
    finalement la solution est assez simple:
    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
    # -*- coding: utf-8 -*-
     
    class Main(object):
        def public(self):
            text = self._protected()
            print("Je suis %s" %text)
            print("et j'appel une fonction " + self.__private())
     
        def _protected(self):
            return "la fonction protégée de Main"
     
        def __private(self):
            return "privée"
     
    class Fille(Main):
        def public(self):
            Main.public(self)
     
        def _protected(self):
            return "la fonction protégée de Fille"
     
    m = Main()
    f = Fille()
     
    m.public()
    f.public()
    print "J'appel une fonction protégée de " + f._protected()
    print "J'appel une fonction privée " + f._Main__private()
    Résultat:
    Je suis la fonction protégée de Main
    et j'appel une fonction privée
    Je suis la fonction protégée de Fille
    et j'appel une fonction privée
    J'appel une fonction protégée de la fonction protégée de Fille
    J'appel une fonction privée privée


    finalement on peut même forcer la main aux fonctions privées

    Merci encore !

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 40
    Points : 23
    Points
    23
    Par défaut
    Citation Envoyé par VinsS Voir le message
    Il est normal que tu aies le résultat de Main.__private() et pas normal que tu attendes le résultat de Fille.__private().

    En général on évite ce genre de construction d'ailleurs.
    Ok, petite question qu'en est-il de la fonction __init__ ? c'est un cas particulier je suppose car après test on peut faire
    dans la classe Fille

  11. #11
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 180
    Points : 321
    Points
    321
    Par défaut
    La méthode __init__, si elle est définie est automatiquement appelée
    à l'instanciation d'une classe.

    En python, lorsqu'on redéfinit une méthode dans une classe fille, celle-ci
    écrasecelle de la classe mère.

    Donc si on veut que le code de la classe mère soit quand même exécuté depuis la classe fille, il faut le faire explicitement.

    Dans le cas de la méthode __init__ cela donne un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Mother.__init__(self)
    Ne pas oublier de passer self en argument.

    Quand on instanciera un objet de la classe Child, tout le code défini dans l'init de la classe mère sera exécuté.

    Nb : En général, évitez de nommer vos propre méthode __ quelque chose __
    sauf quand vous voulez que python les appelle automatiquement dans certaines situations.

    Ainsi, lorsqu'on crée une méthode __repr__ il faut qu'elle retourne une chaîne de caractères. Celle-ci sera invoquée par la fonction intégrée de python nommée repr.
    Idem lorsqu'on crée une méthode __str__ qui sera invoquée non seulement par la fonction str(objet) mais aussi par la fonction print(objet).

    Cela n'a l'air de rien mais c'est particulièrement puissant. En effet, le créateur de la fonction intégrée str par exemple n'a pas à se soucier des types de données qu'elle est censée gérer. Il faut et il suffit que l'objet passé en argument ait une méthode __str__.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 40
    Points : 23
    Points
    23
    Par défaut
    merci pour ces informations, en effet c'est très intéressant et assez puissant !

Discussions similaires

  1. [C#] Problème d'héritage, aide svp :(
    Par choas dans le forum Windows Forms
    Réponses: 12
    Dernier message: 06/05/2006, 12h46
  2. problème constructeur + héritage
    Par BOLARD dans le forum C++
    Réponses: 10
    Dernier message: 13/04/2006, 09h11
  3. [AS2] Problème d'héritage
    Par wwave dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 27/01/2006, 10h26
  4. Problème d'héritage ?
    Par Romanops dans le forum WinDev
    Réponses: 2
    Dernier message: 16/11/2005, 18h18
  5. Problème d'héritage d'une méthode protégée
    Par shenron666 dans le forum C++
    Réponses: 9
    Dernier message: 29/04/2005, 00h17

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