Cours
Que sont les getters et setters ?
- Getters : méthodes de la programmation orientée objet (POO) qui permettent d'accéder aux attributs privés d'une classe.
- Setters : méthodes de la POO qui permettent d'affecter une valeur aux attributs privés d'une classe.
Attribut privé : encapsulation
Si vous n'êtes pas à l'aise avec les attributs privés ou les méthodes privées en Python, lisez cet article DataCamp.
Voyons comment implémenter un attribut privé en Python.
class SampleClass:
def __init__(self, a):
## private varibale or property in Python
self.__a = a
## getter method to get the properties using an object
def get_a(self):
return self.__a
## setter method to change the value 'a' using an object
def set_a(self, a):
self.__a = a
SampleClass comporte trois méthodes.
-
__init__ : initialise les attributs ou propriétés d'une classe.
- __a : c'est un attribut privé.
- get_a : permet de récupérer la valeur de l'attribut privé a.
- set_a : permet de définir la valeur de a via un objet de la classe.
Vous ne pouvez pas accéder directement aux variables privées en Python. D'où l'intérêt d'implémenter un getter.
Voyons comment cette classe fonctionne.
## creating an object
obj = SampleClass(10)
## getting the value of 'a' using get_a() method
print(obj.get_a())
## setting a new value to the 'a' using set_a() method
obj.set_a(45)
print(obj.get_a())
10
45
Voilà comment implémenter des attributs privés, getters et setters en Python. C'est l'approche classique utilisée en Java. Écrivons maintenant la même logique de façon plus pythonic.
class PythonicWay:
def __init__(self, a):
self.a = a
Vous n'avez pas besoin de getters ou de setters pour accéder ou modifier les attributs : on peut y accéder directement par leur nom.
Voyons cela.
## Creating an object for the 'PythonicWay' class
obj = PythonicWay(100)
print(obj.a)
100
Quelle est la différence entre ces deux classes ?
- SampleClass masque les attributs et méthodes privés. Elle met en œuvre l'encapsulation propre à la POO.
- PythonicWay ne masque pas les données. Elle n'implémente pas l'encapsulation.
Laquelle privilégier ?
- Cela dépend de votre besoin. Si vous souhaitez des attributs et méthodes privés, vous pouvez implémenter la classe avec des méthodes setters et getters. Sinon, une implémentation simple suffit.
Property
Supposons maintenant que vous vouliez imposer des conditions lors de l'affectation d'une valeur à un attribut dans SampleClass.
Par exemple : si la valeur passée est paire et positive, on l'affecte à l'attribut ; sinon, on affecte la valeur 2.
Implémentons cela en modifiant la méthode set_a() de SampleClass.
class SampleClass1:
def __init__(self, a):
## calling the set_a() method to set the value 'a' by checking certain conditions
self.set_a(a)
## getter method to get the properties using an object
def get_a(self):
return self.__a
## setter method to change the value 'a' using an object
def set_a(self, a):
## condition to check whether 'a' is suitable or not
if a > 0 and a % 2 == 0:
self.__a = a
else:
self.__a = 2
Vérifions cette classe en créant un objet.
## creating an object for the class 'SampleClass1'
obj = SampleClass1(16)
print(obj.get_a())
16
Voyons maintenant comment implémenter cette logique avec le décorateur @property.
class Property:
def __init__(self, var):
## initializing the attribute
self.a = var
@property
def a(self):
return self.__a
## the attribute name and the method name must be same which is used to set the value for the attribute
@a.setter
def a(self, var):
if var > 0 and var % 2 == 0:
self.__a = var
else:
self.__a = 2
@property permet d'accéder à la valeur d'un attribut privé sans recourir à un getter explicite. Il suffit d'ajouter @property devant la méthode qui renvoie la variable privée.
Pour définir la valeur de la variable privée, on utilise @nom_de_méthode.setter devant la méthode servant de setter.
Testons la classe Property pour vérifier que les décorateurs fonctionnent correctement.
## creating an object for the class 'Property'
obj = Property(23)
print(obj.a)
2
@a.setter affecte la valeur de a après avoir vérifié les conditions définies dans la méthode. Une autre manière d'utiliser property consiste à...
class AnotherWay:
def __init__(self, var):
## calling the set_a() method to set the value 'a' by checking certain conditions
self.set_a(var)
## getter method to get the properties using an object
def get_a(self):
return self.__a
## setter method to change the value 'a' using an object
def set_a
(self, var):
## condition to check whether var is suitable or not
if var > 0 and var % 2 == 0:
self.__a = var
else:
self.__a = 2
a = property(get_a, set_a)
Passez le getter et le setter à property puis affectez le résultat au nom que vous souhaitez utiliser comme attribut de classe.
## creating an object for the 'AnotherWay' class
obj = AnotherWay(28)
print(obj.a)
28
Rendez les méthodes de setter et de getter privées pour les masquer. Faisons-le.
class FinalClass:
def __init__(self, var):
## calling the set_a() method to set the value 'a' by checking certain conditions
self.__set_a(var)
## getter method to get the properties using an object
def __get_a(self):
return self.__a
## setter method to change the value 'a' using an object
def __set_a(self, var):
## condition to check whether var is suitable or not
if var > 0 and var % 2 == 0:
self.__a = var
else:
self.__a = 2
a = property(__get_a, __set_a)
Vérifions que tout fonctionne correctement.
## creating an object for the 'AnotherWay' class
obj = FinalClass(12)
print(obj.a)
12
Conclusion
Vous savez maintenant comment implémenter l'encapsulation en Python et la différence entre setter, getter et property.
Si vous débutez en Python, nous vous recommandons le cours gratuit de DataCamp : Introduction to Python.
Si vous avez des questions sur cet article, posez-les dans les commentaires. Bon code !