Résolue

Méthode privée

# Méthodes # Orienté objet

Gabriel Trouvé

Mentor

Bonsoir,


Je viens de réussir l'exercice sur les méthodes privées.


J'ai du mal à comprendre concrètement ce que ça permet de faire ou ne pas faire en fait.

En gros, il s'agit de méthodes utilisées uniquement dans la méthode fait_du_café ?

On ne peut pas faire appel à chauffe eau et moud café autrement que dans fait du café ?

Il s'agit de méthode "intermédiaires" qui permettent de construire une autre méthode ?


Merci d'avance


class MachineACafe:
    def __init__(self):
        self.temperature_eau = 0


    def __chauffe_eau(self):
        self.temperature_eau = 100
        print("L'eau est chaude.")


    def __moud_cafe(self):
        print("Café moulu avec succès.")


    def fait_du_cafe(self):
        self.__moud_cafe()
        self.__chauffe_eau()
        print("Le café est prêt")




machine = MachineACafe()
machine.fait_du_cafe()

Thibault houdon

Mentor

Salut Gabriel :)


Pour bien comprendre l'intérêt de ces méthodes, il faut penser par rapport à un travail d'équipe.


Les méthodes privées sont destinées à l'utilisation interne de la classe. Dis-toi que pour l'instant tu travailles tout seul sur ton code donc effectivement dans ces conditions, tu te demandes avec raison à quoi cela peut servir.


Maintenant imagine que tu travailles avec d'autres personnes et que tu crées cette classe pour qu'elle soit utilisée par tes collègues.


On va reprendre l'exemple de la machine à café et faire une analogie avec la vie réelle.


Tu travailles dans un salon de café et donc ce que tu as besoin de faire c'est du café ! Personne n'a besoin d'eau chaude ou de café moulu, mais juste du café fini. Tu crées donc ces méthodes comme privées parce que tes collègues n'utiliseront et n'ont besoin d'être au courant que de la méthode fait_du_cafe.


Mais cela peut changer ! Imagine que finalement dans ton café tu décides aussi de servir du thé. Dans ce cas, il pourrait être intéressant de rendre la méthode __chauffe_eau publique, car elle pourra être utilisée par tes collègues pour servir de l'eau chaude pour le thé.


Dans ce cas-ci tu pourrais aussi te dire que __chauffe_eau n'est pas suffisamment explicite. On peut chauffer de l'eau pour différents usage (du café, comme du thé). Il serait donc probablement plus pertinent dans ce cas de garder la méthode privée et de créer une autre méthode pour faire le thé :


import time

class MachineDuBar:
    def __init__(self):
        self.temperature_eau = 0
        self.eau = 0
        self.sachet = 0

    def __chauffe_eau(self):
        self.temperature_eau = 100
        print("L'eau est chaude.")


    def __moud_cafe(self):
        print("Café moulu avec succès.")


    def fait_du_cafe(self):
        self.__moud_cafe()
        self.__chauffe_eau()
        print("Le café est prêt")

    def __infuse_the(self):
        time.sleep(180)
        self.eau += 200 # quantité d'eau en ML
        self.sachet += 1
return self.eau + self.sachet

    def fait_du_the(self):
        self.__chauffe_eau()
        self.__infuse_the()
        print("Le thé est prêt")



machine = MachineACafe()
machine.fait_du_the()


C'est un exemple très schématique mais j'espère que ça te permet de comprendre le mécanisme.


Je te donne un exemple un peu plus utile et concret pour que tu comprennes bien.


Imagine que tu sois développeur pour une banque. Tu dois coder une classe qui permette de gérer les dépôts et retraits de la banque. Cette classe sera utilisée par tes collègues qui gèrent le site web pour effectuer les dépôts et les retraits effectués par les utilisateurs via l'interface du site web.


Voici à quoi pourrait ressembler la classe :

class Banque:
    def __init__(self, solde_initial):
        self.__solde = solde_initial


    def deposer(self, montant):
        self.__solde += montant


    def retirer(self, montant):
        if self.__montant_valide(montant):
            self.__solde -= montant
        else:
            print(f"Impossible de retirer {montant} : solde insuffisant.")


    def afficher_solde(self):
        print(f"Votre solde est de {self.__solde}.")


    def __montant_valide(self, montant):
        return montant <= self.__solde

    

Tu vois ici que j'ai décidé de rendre privée la méthode __montant_valide parce que c'est une méthode qui ne sert qu'à faire des vérifications à l'intérieur de ta classe. Tes collègues n'ont pas besoin de vérifier si le montant est valide, car tu as déjà implémenté cette vérification dans la méthode retirer. Si le retrait est trop important, ils seront prévenus.


Là encore : tout est une question de choix par rapport à ce que tu as besoin de faire. Ta classe peut évoluer. Si demain tes collègues t'indique qu'il serait intéressant pour l'utilisateur de savoir via une interface si le montant qu'il souhaite retirer est possible, tu pourrais choisir de rendre cette méthode publique pour leur permettre de l'utiliser !


Tu remarqueras également que dans cet exemple j'ai également rendu privée la variable __solde.


De la même façon que les méthodes, je considère ici que les gens qui utilisent ta classe n'ont pas à utiliser / modifier directement cette variable. S'ils veulent modifier le solde, ils sont ainsi obligés de passer par les méthodes deposer et retirer. Cela permet d'éviter les erreurs car ils ne pourront pas retirer un montant trop important, car tu fais la vérification dans la méthode retirer (ce qui aurait été possible en modifiant directement la variable).


Dernier mécanisme intéressant, quand tu utilises la fonction dir pour vérifier ce qui est disponible sur une classe, tu verras que les méthodes privées ne sont pas affichées à la fin de la liste, exemple avec la classe Banque ci-dessus :


>>> dir(Banque)
['_Banque__montant_valide', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'afficher_solde', 'deposer', 'retirer']


(Tu peux faire fi de toutes les méthodes "dunder" __foo__ qui sont contenues dans toutes les classes).


Tu vois qu'à la fin, seul les méthodes afficher_solde, deposer et retirer sont affichées. La méthode montant valide est affichée mais uniquement via la classe au tout début de la liste.


J'espère que c'est plus clair pour toi, c'est clairement le genre de mécanisme qu'il est plus facile de comprendre en situation. Et Python est très permissif également, d'autres langages te forceraient à utiliser ces mécanismes là où avec Python tu vois que tu pourrais tout faire avec des méthodes publiques sans que cela ne pose de problèmes. Ce sont donc plus de bonnes pratiques que tu pourras utiliser sur le long terme, pour avoir un code facile à comprendre et à utiliser. Mais ne t'en fais pas, j'ai travaillé dans plusieurs entreprises dans lesquels des développeurs avec déjà quelques années d'expériences ne connaissaient pas ces mécanismes et faisaient tout avec des méthodes publiques ;)


Bonne continuation et joyeuses fêtes à toi !

Gabriel Trouvé

Mentor

Pfiou Merci Thibault !

Je vais devoir revenir dessus par la suite je pense lol. (pour bien comprendre).

ça me fait une donc en plus dans mes questions :).

Merci et bonnes fêtes à toi aussi !

Inscris-toi

(c'est gratuit !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.