cours
Explication des méthodes privées en Python
Dans la programmation orientée objet (POO), une approche de la conception de logiciels, nous utilisons des "objets" pour modéliser les entités du monde réel. Un objet est une structure de données avec des attributs (données) et des méthodes (fonctions) qui agissent sur les données. Les systèmes complexes peuvent être plus faciles à concevoir avec des objets.
Apprenez-en plus sur les fondamentaux et les concepts de génie logiciel derrière la POO en commençant notrecours programmation orientée objet avec Python.
L'encapsulation est un concept fondamental de la POO. Il s'agit de regrouper les données et les méthodes d'un objet et d'en cacher les détails au monde extérieur. Considérez l'encapsulation comme un processus qui crée une "capsule" (un objet) avec ses propres données et les moyens de les manipuler.
L'objectif principal de l'encapsulation est le suivant :
- Empêcher l'accès direct aux données (intégrité des données).
- Simplifier le système en ne montrant que ce qui est nécessaire (abstraction).
Les méthodes privées sont essentielles pour réaliser cette encapsulation en cachant les détails de l'implémentation interne d'une classe.
En rendant une méthode privée, vous indiquez aux autres programmeurs que cette méthode n'est pas destinée à être accessible directement. Cela permet d'éviter les bogues et les erreurs en garantissant que l'état interne d'un objet ne peut être modifié que de manière contrôlée.
Nous présenterons ici les méthodes privées, la syntaxe pour les définir, la mise en œuvre des méthodes privées dans des exemples concrets et les meilleures pratiques pour les utiliser.
Que sont les méthodes privées ?
Dans la programmation orientée objet (POO), les méthodes privées sont des fonctions d'une classe conçues pour un usage interne uniquement. Ils encapsulent la fonctionnalité d'une classe, garantissant que son fonctionnement interne reste à l'abri de toute interaction externe.
Cette encapsulation fournit une couche d'abstraction, permettant à la classe de garder le contrôle sur son état et son comportement internes et de modifier son implémentation sans affecter le code externe qui s'appuie sur elle.
En Python, la convention pour désigner les méthodes privées consiste à préfixer le nom de la méthode par un simple trait de soulignement (_) ou un double trait de soulignement (__). Il s'agit d'un indice pour les développeurs quant à la portée prévue de la méthode et d'une simple convention.
Bien que cette convention n'impose pas une confidentialité stricte comme dans certains autres langages, il s'agit d'une pratique bien respectée au sein de la communauté Python pour signaler l'utilisation prévue de la méthode. Nous approfondirons ultérieurement ces aspects de manière plus complète.
La syntaxe des méthodes privées
Il existe deux manières différentes de définir des méthodes privées, que nous verrons à travers des exemples.
Nous pouvons définir une méthode privée en utilisant un seul trait de soulignement avant le nom de la fonction :
class MyClass:
def _private_method(self):
print("This is a private method")
Cette définition n'est qu'une convention pour les programmeurs, car la fonction reste accessible en dehors de la classe, bien qu'elle ne soit pas recommandée.
Si c'est la première fois que vous entendez parler des classes en Python, nous vous recommandons de consulter d'abord notre tutoriel pour débutants sur les classes.
Créons un objet et essayons d'accéder à la méthode privée créée :
# Creating an object
obj = MyClass()
# Accessing from outside
obj._private_method() # Not recommended to call directly, but possible
Il existe une autre syntaxe pour définir les méthodes privées en Python, qui utilise des doubles traits de soulignement. Il se présente comme suit : :
class MyClass:
def __private_method(self):
print("This is a private method")
obj = MyClass()
# obj.__private_method() # This will raise an AttributeError
Lorsque nous essayons d'accéder à la méthode privée depuis l'extérieur de la classe, une erreur d'attribut (AttributeError) se produit, signalant qu'il n'est pas possible d'y accéder directement en utilisant le nom de la fonction.
Pour résumer la syntaxe des méthodes privées en Python :
- Un seul trait de soulignement : il s'agit simplement d'une convention pour les programmeurs ; il est accessible en dehors de la fonction.
- Double trait de soulignement : il n'est pas possible d'accéder à la fonction en dehors de son nom. Il est toujours possible d'y accéder par le biais du "Name Mangling" que nous verrons plus loin dans ce tutoriel.
Implémentation de méthodes privées en Python
Prenons un exemple concret : la classe BankAccount, sécurisée et conviviale, permet de gérer les transactions financières d'un utilisateur. Les exigences relatives aux comptes bancaires sont les suivantes :
- La classe doit encapsuler le solde du titulaire du compte, permettant les dépôts et les retraits tout en garantissant que le solde ne peut pas être manipulé directement en dehors de la classe.
- La classe doit faciliter les transferts sûrs entre comptes, en mettant à jour le solde du compte destinataire sans exposer le mécanisme interne de modification du solde.
- La solution doit respecter les principes de la programmation orientée objet, en particulier l'encapsulation et l'abstraction, afin de préserver l'intégrité des données du compte et de fournir une interface claire et simple pour interagir avec le compte.
Bien entendu, un compte bancaire nécessite d'autres fonctionnalités telles que la vérification du solde, la conversion des devises et la gestion des intérêts - mais pour rester simple, nous ne les prendrons pas en compte dans notre implémentation.
Mettons en œuvre cette solution et comprenons le code.
class BankAccount:
def __init__(self, account_holder, initial_balance=0):
self.account_holder = account_holder
self.__balance = initial_balance # Private attribute
def deposit(self, amount):
if amount > 0:
self.__balance += amount
print(f"Deposited ${amount}. New balance: ${self.__balance}")
else:
print("Deposit amount must be positive.")
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
print(f"Withdrew ${amount}. New balance: ${self.__balance}")
else:
print("Insufficient funds or invalid amount.")
def __update_balance(self, amount): # Private method
self.__balance += amount
def transfer(self, amount, other_account):
if 0 < amount <= self.__balance:
self.withdraw(amount)
other_account.__update_balance(amount)
print(f"Transferred ${amount} to {other_account.account_holder}.")
else:
print("Insufficient funds or invalid amount.")
Nous commençons par créer un objet BankAccountclass
, qui englobe tous les comportements et fonctionnalités requis par un objet BankAccount.
La classe BankAccount
possède un attribut privé __balance
et une méthode privée __update_balance
:
- Variable privée (
__balance
) : Il s'agit d'un attribut de la classeBankAccount
qui stocke le solde du compte courant. Il est marqué comme privé en faisant précéder son nom de deux traits de soulignement (__
). Cela signifie qu'il est destiné à être accessible uniquement au sein de la classe elle-même. Par exemple, il est modifié par les méthodes deposit,withdraw
et__update_balance
. L'accès externe à cet attribut n'est pas recommandé. - Méthode privée (
__update_balance
) : L'objectif de cette méthode est de mettre à jour le solde du compte. Elle est appelée par la méthodetransfer
pour mettre à jour le solde du compte du destinataire lors d'une opération de transfert. L'utilisation d'une méthode privée ici permet d'encapsuler la logique de mise à jour du solde, en s'assurant qu'elle ne peut être effectuée que selon les méthodes contrôlées définies par la classe.
N'hésitez pas à créer un nouveau fichier Python, à copier et coller le code ci-dessus et ci-dessous, et à l'exécuter pour le constater par vous-même.
# Using the Bank Account Solution
account1 = BankAccount("John Doe", 1000)
account2 = BankAccount("Jane Doe", 500)
account1.deposit(200)
account1.withdraw(100)
account1.transfer(300, account2)
Vous verrez le résultat ci-dessous :
Deposited $200. New balance: $1200
Withdrew $100. New balance: $1100
Withdrew $300. New balance: $800
Transferred $300 to Jane Doe.
Félicitations ! Vous avez créé votre solution BankAccount en utilisant une méthode privée !
Sur la base des résultats obtenus, nous constatons que les opérations bancaires habituelles, telles que le dépôt, le retrait et le transfert de fonds, suivent le comportement logique habituel d'un compte bancaire.
La méthode __init__ : est-ce une méthode privée ?
Vous avez probablement remarqué la méthode __init__
utilisée dans l'exemple du compte bancaire. Étant donné qu'elle utilise également la syntaxe du double trait de soulignement, vous pouvez vous demander s'il s'agit également d'une méthode privée.
La méthode __init__
n'est pas considérée comme une méthode privée au même titre que les méthodes précédées d'un double soulignement pour la confidentialité.
Il fait plutôt partie des méthodes spéciales de Python, souvent appelées méthodes "dunder" (abréviation de "double underscore"), qui ont un but spécifique dans le langage. D'autres exemples de ces méthodes spéciales sont __str__
, __repr__
, et __del__
.
Voyons comment cette méthode spéciale a été utilisée dans notre exemple :
class BankAccount:
def __init__(self, account_holder, initial_balance=0):
self.account_holder = account_holder
self.__balance = initial_balance
Comme nous le voyons, la méthode __init__
est le constructeur d'une classe. Elle est automatiquement appelée lors de la création d'une nouvelle instance de la classe et sert à initialiser les attributs de l'objet. Pour la classe BankAccount
, la méthode __init__
est utilisée pour définir les valeurs initiales des attributs account_holder
et __balance
.
Concepts avancés : La confusion des noms en Python
Plus tôt dans notre définition, nous avons mentionné que les méthodes privées en Python ne sont qu'une convention, et que le langage Python n'applique pas strictement la confidentialité, contrairement à d'autres langages de programmation.
A juste titre, nous avons vu que les méthodes privées étaient accessibles directement lorsque l'on utilisait un simple trait de soulignement, mais que l'accès était restreint lorsque l'on utilisait un double trait de soulignement.
Mais pourquoi ? En raison d'un concept appelé "name mangling" en Python.
Lorsque vous préfixez un nom d'attribut par un double trait de soulignement, Python modifie automatiquement le nom en ajoutant un simple trait de soulignement et le nom de la classe avant le nom de l'attribut d'origine.
Ce nom modifié est la façon dont l'attribut est stocké en interne dans la classe. Le processus de modification du nom de cette manière est connu sous le nom de "name mangling".
La confusion des noms est utile pour deux raisons :
- Prévenir les conflits de noms : Dans l'héritage, si une sous-classe définit un attribut portant le même nom qu'un attribut de sa superclasse, il y a conflit entre les deux. La confusion des noms permet d'éviter ce problème en garantissant que les noms sont uniques pour chaque classe.
- Un certain degré de confidentialité : Bien que Python ne dispose pas de véritables attributs privés, la manipulation des noms permet de rendre les attributs moins accessibles depuis l'extérieur de la classe, offrant ainsi un certain degré de confidentialité.
Voyons un exemple pour mieux comprendre.
class MyClass:
def __init__(self):
self.__private_attribute = "I am private"
def __private_method(self):
print("This is a private method")
obj = MyClass()
print(obj.__private_attribute) # This will raise an AttributeError
Dans cet exemple, les noms __private_attribute
et __private_method
sont confondus. En interne, ils sont enregistrés sous les noms _MyClass__private_attribute
et _MyClass__private_method
, respectivement. Si vous essayez d'y accéder en utilisant leur nom d'origine depuis l'extérieur de la classe, vous obtiendrez AttributeError
.
Toutefois, vous pouvez toujours y accéder en utilisant leur nom abrégé :
print(obj._MyClass__private_attribute) # This will print "I am private"
obj._MyClass__private_method() # This will print "This is a private method"
Bien que l'altération des noms rende les attributs moins accessibles, il est important de noter qu'il ne s'agit pas d'une méthode infaillible pour garantir la confidentialité en Python. Il s'agit plutôt d'une convention pour indiquer qu'un attribut est destiné à un usage interne au sein de la classe.
Meilleures pratiques pour l'utilisation de méthodes et de variables privées
L'exploitation efficace des méthodes et des variables privées nécessite le respect de certaines bonnes pratiques. Ces pratiques permettent de s'assurer que votre code n'est pas seulement fonctionnel, mais aussi clair, facile à maintenir et sûr.
Voici quelques bonnes pratiques à suivre :
- Utilisez un seul trait de soulignement pour les attributs "protégés". Si vous souhaitez indiquer qu'un attribut ou une méthode est destiné à être utilisé au sein de la classe et de ses sous-classes, mais pas à être utilisé à l'extérieur, préfixez-le par un simple trait de soulignement (
_
). Il s'agit d'une convention de Python qui signale aux autres développeurs que l'attribut ou la méthode est "protégé" et qu'il ne faut pas y accéder directement. - Utilisez un double trait de soulignement pour les attributs "privés". Si vous souhaitez rendre un attribut ou une méthode moins accessible en dehors de la classe afin d'éviter toute modification ou utilisation accidentelle, préfixez-le par un double trait de soulignement (
__
). Cela entraîne une confusion des noms et rend plus difficile (mais pas impossible) l'accès à l'attribut ou à la méthode depuis l'extérieur de la classe. - Utilisez des méthodes privées pour la logique interne. Les méthodes privées (celles qui sont précédées d'un simple ou d'un double trait de soulignement) sont un excellent moyen d'encapsuler la logique interne de votre classe. Utilisez-les pour effectuer des tâches spécifiques à l'implémentation de la classe et qui ne doivent pas être exposées dans le cadre de l'interface publique de la classe.
Enfin, il est important de respecter les meilleures pratiques en matière de codage. Respectez les conventions de dénomination et utilisez-les de manière cohérente dans votre base de code. Cela rend votre code plus facile à comprendre et à maintenir pour les autres développeurs et pour vous-même.
Conclusion
Ce tutoriel vous a présenté les concepts qui sous-tendent les méthodes privées, leur syntaxe et le moment où vous pouvez les utiliser. Nous avons également vu de nombreux exemples illustrant comment vous pouvez potentiellement les utiliser dans votre prochain projet de codage. Enfin, nous avons examiné quelques bonnes pratiques à garder à l'esprit lorsque vous les utilisez.
Pour un apprentissage plus approfondi, vous pouvez consulter le cursus de compétences en programmation Python et le cours de programmation orientée objet en Python.
En tant que data scientist senior, je conçois, développe et déploie des solutions d'apprentissage automatique à grande échelle pour aider les entreprises à prendre de meilleures décisions basées sur les données. En tant que rédacteur spécialisé dans la science des données, je partage mes apprentissages, mes conseils de carrière et des tutoriels pratiques approfondis.
Poursuivez votre apprentissage de Python !
cours
Programmation orientée objet en Python
cours