Programmation orientée objet en Python: Classe, méthode et attribut

ProgrammationOrienteeObjetPython

Introduction aux objets et méthodes

En Python, toutes les données, y compris les nombres et les chaînes sont des objets. Un nombre est un objet, une chaîne est un objet, une liste est un objet, un dictionnaire est un objet et chaque donnée est un objet. Les objets de même nature ont le même type.

Un objet contient deux parties : les propriétés et les méthodes. Les propriétés permettent de stocker la valeur de l’objet et les méthodes représentent les fonctions permettant de manipuler la valeur de l’objet.

Par exemple, la classe list permet de créer des objets dans lesquels on peut stocker une séquence d’éléments. En plus, elle nous offrent des méthodes comme append(), insert() et pop() pour manipuler ces éléments.

Vous pouvez utiliser la fonction id et la fonction type pour obtenir l’identifiant et le type d’un objet, respectivement. Par exemple :

>>> n = 3 # n est un entier
>>>id(n)
505408904
>>>type(n)
<class 'int'>
>>> f = 3.0 # f est un flottant
>>>id(f)
26647120
>>>type(f)
<class 'float'>
>>> s = "Welcome" # s est une chaîne de caractères
>>>id(s)
36201472
>>> type(s)
<class 'str'>
>>>

L’identifiant d’un objet est un entier qui est assuré d’être unique et constant pour cet objet au cours de sa vie. Un numéro unique, rien de plus et rien de moins. Considérez-le comme numéro de CIN (carte d’identité nationale) pour les objets Python.

L’identifiant d’un objet représente son adresse en mémoire. Par conséquent, deux objets ayant le même identifiant représentent la même donnée.

L’identifiant d’un objet est un nombre entier unique attribué automatiquement par Python lorsque le programme est exécuté. Cet identifiant ne sera pas changé au cours de l’exécution du programme.

Cependant, Python peut attribuer un identifiant différent chaque fois que le programme est exécuté. Le type de la variable est déterminé par Python en fonction de sa valeur. La ligne 2 affiche l’identifiant de la variable numérique n.

La ligne 3 montre l’id Python assigné la variable n, ainsi que son type affiché dans la ligne 4.
En Python, le type d’un objet est défini par une classe. Par exemple, la classe d’une chaîne de caractères est str (ligne 15), la classe d’un nombre entier est int (ligne 5), et pour un flottant est float (ligne 10). Le terme «classe» provient de la programmation orientée objet. En Python, les classes et les types sont synonymes.

Les fonctions « id » et « type » sont rarement utilisés dans la programmation, mais ils sont de bons outils pour apprendre plus sur les variables.

Une variable en Python est une référence à un objet. La figure suivante montre la relation entre les variables et les objets pour le code précédent.

id_type_python

La déclaration n = 3 dans la ligne 1 attribue la valeur 3 à n, qui en fait attribue 3 à un objet int référencé par la variable n.

Pour n = 3, nous disons : n est une variable entière qui détient la valeur 3. Strictement parlant, n est une variable qui fait référence à un objet int dont la valeur est 3. Pour plus de simplicité, il est bon de dire « n est une variable int avec la valeur 3 ».

Vous pouvez effectuer des opérations sur un objet. Les opérations sont définies en utilisant des fonctions. Les fonctions pour les objets sont appelées méthodes en Python. Les méthodes ne peuvent être appelées qu’à partir d’un objet spécifique.

Par exemple, le type chaîne de caractères a des méthodes telles que lower () et upper (), qui retournent une nouvelle chaîne de caractères en minuscules et majuscules, respectivement. Voici quelques exemples de la façon d’appeler ces méthodes:

>>> s = "Welcome"
>>> s1 = s.lower() # Appeler la méthode lower()
>>> s1
'welcome'
>>> s2 =s.upper()# Appeler la méthode upper()
>>> s2
'WELCOME'
>>>

La ligne 2 appelle la méthode s.lower () de l’objet s afin de renvoyer une nouvelle chaîne de caractères en minuscules et l’assigner à s1.

La ligne 5 appelle la méthode upper() de l’objet s afin de renvoyer une nouvelle chaîne de caractères en majuscules et l’assigner à s2.

Comme vous pouvez le voir dans l’exemple précédent, la syntaxe pour appeler une méthode d’un objet est object.method ().

Une autre méthode utile des chaîne de caractères est strip(), qui peut être utilisé pour enlever les caractères d’espacement des deux extrémités d’une chaîne de caractères. Les caractères ”, \ t, \ f, \ r et \ n sont connus comme des caractères blancs.

Par exemple,

>>> s = "\t Welcome \n"
>>> s1 = s.strip()# Appeler la méthode strip()
>>> s1
'Welcome'
>>>

Qu’est-ce qu’une classe ?

Une classe définit les propriétés et les comportements des objets. La programmation orientée objet (POO) implique l’utilisation d’objets pour créer des programmes.

Un objet représente une entité dans le monde réel qui peut être nettement identifié. Par exemple, un étudiant, un bureau, un cercle, un bouton, et même un prêt peuvent tous être considérés comme des objets. Un objet a un identifiant, un état et un comportement uniques.

L’état d’un objet (également connu sous le nom de ses propriétés ou attributs) est représenté par des variables. Un objet Cercle, par exemple, a un rayon, qui est une propriété qui caractérise un cercle. Un objet rectangle a les données Largeur et Longueur, qui sont des propriétés qui caractérisent un rectangle.

Python utilise des méthodes pour définir le comportement d’un objet (également connu sous le nom de « actions »). Rappelons que les méthodes sont définies comme des fonctions. Vous incitez un objet à effectuer une action en appelant une de ses méthodes. Par exemple, vous pouvez définir des méthodes nommées ObtenirSurface() et ObtenirPerimetre () pour les objets de la classe« Cercle ». Un objet de la classe « Cercle » peut alors appeler la méthode ObtenirSurface() pour retourner sa surface et la méthode ObtenirPerimetre () pour retourner son périmètre.

Les objets du même genre sont définis en utilisant la même classe. La relation entre les classes et les objets est analogue à celle entre une recette tarte-aux-pommeset des tartes aux pommes. Vous pouvez faire autant de tartes aux pommes (objets) que vous voulez à partir d’une recette unique (classe).

Une classe Python utilise des variables pour stocker les données et définit des méthodes pour manipuler ses données. Une classe est un contrat, aussi parfois appelé un modèle, qui définit les données et les méthodes d’un objet.

Un objet est une instance d’une classe, et vous pouvez créer de nombreuses instances d’une classe. La création d’une instance/objet à partir d’une classe est appelée instanciation. Les termes objet et instance sont souvent utilisés de manière interchangeable. Un objet est une instance et une instance est un objet.

classe_objet_python

Définition de classes

En plus d’utiliser des variables pour stocker les données et définir des méthodes, une classe fournit une méthode spéciale, __init__. Cette méthode, connue sous le nom d’un initialiseur, est appelée pour initialiser un nouvel objet lors de sa création. Un initialiseur peut effectuer n’importe quelle action, mais les initialiseurs sont conçus pour effectuer des actions d’initialisation, telles que la création de données d’un objet avec des valeurs initiales.

Python utilise la syntaxe suivante pour définir une classe:

class NomDeLaClass:
   Initialiseur
   Méthodes

Le code ci-dessous définit la classe Cercle. Le nom de la classe est précédé par le mot-clé classe et suivi par deux points « : ». L’initialiseur est toujours nommé _ _init_ _ (ligne 4), qui est une méthode spéciale. Notez que la chaîne « init » doit être précédée et suivie de deux caractères de soulignement.

Un attribut (variable) « rayon » est créé par le constructeur (ligne 5). Les méthodes ObtenirPerimetre et ObtenirAire sont définis pour retourner le périmètre et l’aire d’un cercle (lignes 6-9).

import math

class Cercle:
# Construire un objet de type cercle
   def __init__(self, r = 1):
      self.rayon = r

   def ObtenirPerimetre(self):
      return 2 * self.rayon* math.pi

   def ObtenirAire(self):
      return self.rayon* self.rayon* math.pi

   def ChangerRayon(self, r):
      self.rayon = r

Construire des objets

Une fois la classe est définie, vous pouvez en créer des objets en utilisant un constructeur. Le constructeur a deux rôles:

  • Il crée l’objet dans la mémoire.
  • Il appelle la méthode __init__() de la classe pour initialiser l’objet.

Toutes les méthodes, y compris l’initialiseur, ont « self » en tant que premier paramètre. Ce paramètre fait référence à l’objet courant qui appelle la méthode. Le paramètre « self » dans la méthode __init__ est automatiquement défini pour référencer l’objet qui vient d’être créé. Vous pouvez spécifier un nom pour ce paramètre, mais par convention « self » est habituellement utilisé.

La syntaxe utilisée pour appeler un constructeur est:
<strong>NomeDeLaClasse(paramètres)</strong>

La figure ci-dessous montre comment un objet est créé et initialisé. Une fois l’objet est créé, le mot clé self peut être utilisé pour faire référence à l’objet.

syntaxeClassePython

Les arguments du constructeur correspondent aux paramètres de la méthode __init__ sans compter le paramètre self. Par exemple, étant donné que la méthode __init__ dans la ligne 4du code ci-dessus est défini comme :
__init __ (self, rayon = 1), vous devez utiliser l’expression Cercle (5) pour construire un objet Cercle de rayon 5. La figure suivante montre l’effet de la construction d’un objet Cercle en utilisant l’instruction « Cercle (5) ». D’abord, un objet Cercle est créé dans la mémoire, puis l’initialiseur est appelé pour définir un rayon de valeur 5.

CreationObjetPython

L’initialiseur de la classe Cercle a une valeur de rayon par défaut de 1. Le constructeur suivant crée un objet cercle de rayon par défaut 1:

Cercle()

Accès aux membres d’objets

Les membres d’un objet représentent ses attributs et ses méthodes. Les attributs sont également appelées attributs d’instance, parce que chaque attribut est n’est créé qu’après la construction de l’objet.

Pour accéder aux attributs d’un objet ou appeler l’une de ces méthodes, vous devez affecter l’objet à une variable en utilisant la syntaxe suivante:

VariableObjet =NomDeLaClass(arguments)

Par exemple :

c1 = Cercle(5)
c2 = Cercle()

Vous pouvez accéder aux attributs de l’objet et appeler ses méthodes en utilisant l’opérateur point (.) comme suit:

VariableObjet.attribut_1
VariableObjet.methode_1(paramètres)

Par exemple, le code suivant accède à l’attribut d’instance «rayon » (ligne 3), puis appelle la méthode ObtenirPerimetre (ligne 5) et la méthode ObtenirAire (ligne 7). Notez que la ligne 1 importe la classe Cercle définie ci-dessus.

>>>from Cercle import Cercle
>>> c = Cercle(5)
>>>c.rayon
5
>>>c.ObtenirPerimetre()
31.41592653589793
>>>c.ObtenirAire()
78.53981633974483
>>>

Habituellement, vous créez un objet et vous l’assigner à une variable. Plus tard, vous pouvez utiliser la variable pour faire référence à l’objet. Parfois, un objet n’a pas besoin d’être référencé plus tard. Dans ce cas, vous pouvez créer un objet sans l’attribuer explicitement à une variable, comme indiqué ci-dessous:

print("L’aire est", Cercle(5).ObtenirAire())

La déclaration crée un objet Cercle et appelle sa méthode ObtenirAire pour retourner sa surface. Un objet créé de cette manière est connue comme un objet anonyme.

Le paramètre Self

Comme mentionné précédemment, le premier paramètre pour chaque méthode d’instance est self. Ce paramètre est utilisé dans la mise en œuvre des méthodes d’instance, mais il n’est pas utilisé lorsqu’une méthode d’instance est appelée. Alors, qu’est-ce que ce paramètre self? Pourquoi Python a en besoin?

« self » est un paramètre qui fait référence à l’objet lui-même. En utilisant self, vous pouvez accéder aux membres (attributs et méthodes) de l’objet dans une définition de classe. Par exemple, vous pouvez utiliser la syntaxe self.x pour accéder à l’attribut d’instance x et la syntaxe self.m1() pour appeler la méthode d’instance m1 pour l’objet self comme le montre la figure suivante.

PorteeSelf

La portée d’un attribut d’instance est toute la classe une fois déclaré dans la méthode __init__().Dans la figure ci-dessus, self.x est un attribut d’instance créé dans la méthode __init__. Il est accessible dans la méthode m2. L’attribut d’instance self.y est initialisé à la valeur 2 dans la méthode m1 et on a y assigné la valeur 3 dans le code de la méthode m2.

Notez que vous pouvez également créer des variables locales dans une méthode. La portée d’une variable locale est la méthode elle-même. La variable locale z est créée dans la méthode m1, alors on ne peut pas y accéder qu’à l’intérieur de la méthode m1. Par exemple, on ne peut pas accéder à la valeur de z à partir de la méthode m2.

Exemples: Utilisation des classes

Les sections précédentes ont démontré le concept de classe et d’objets. Vous avez appris à définir une classe avec l’initialiseur, attributs d’instances et méthodes, et comment créer un objet avec le constructeur.

Cette section présente un programme de test qui construit trois objets de la classe cercle avec des rayons de 1, 25 et 125, puis affiche le rayon et l’aire de chaque cercle. Ensuite, le programme change le rayon du second objet à 100 et affiche son nouveau rayon et son aire.

from Cercle import Cercle

def main():

   # Créer un cercle d'un rayon de 1
   cercle1 = Cercle()
   print("L'aire du cercle dont le rayon égal à ", cercle1.rayon, "est ", cercle1.ObtenirAire() )

   # Créer un cercle d'un rayon de 25
   cercle2 = Cercle(25)
   print("L'aire du cercle dont le rayon égal à ", cercle2.rayon , "est ", cercle2.ObtenirAire())

   # Créer un cercle d'un rayon de 125
   cercle3 = Cercle(125)
   print("L'aire du cercle dont le rayon égal à ", cercle3.rayon, "est", cercle3.ObtenirAire())

   # Modifier le rayon cercle
   cercle2.rayon = 100 # ou cercle2.ChangerRayon(100)
   print("L'aire du cercle dont le rayon égal à ", cercle2.rayon, "est", cercle2.ObtenirAire())

main() # Appeler la fonction main

Voici la sortie du programme :

L'aire du cercle dont le rayon égal à 1 est 3.141592653589793
L'aire du cercle dont le rayon égal à 25 est 1963.4954084936207
L'aire du cercle dont le rayon égal à 125 est 49087.385212340516
L'aire du cercle dont le rayon égal à 100 est 31415.926535897932

Cacher les attributs d’instance

Créer des attributs d’instance privés protège les données et rend la classe facile à entretenir.
Vous pouvez accéder aux attributs d’instance directement à partir d’un objet. Par exemple, le code suivant vous permet d’accéder au rayon du cercle c par le moyen de l’expression c.rayon:

>>> c = Cercle(5)
>>>c.rayon = 5.4 # Accéder à l’attribut d’instance directement

>>>print(c.rayon) # Accéder à l’attribut d’instance directement
5.4
>>>

Cependant, l’accès direct à un attribut d’instance d’un objet n’est pas de bonne pratique pour deux raisons:

  • Premièrement, les données peuvent être altérées. Par exemple, un utilisateur peut attribuer une valeur négative au rayon d’un cercle. Dans ce cas, comment pouvez-vous éviter ça ?
  • Deuxièmement, la classe devient difficile à maintenir et vulnérable aux bogues. Supposons que vous voulez modifier la classe Cercle pour veiller à ce que le rayon est non négatif après d’autres programmes ont déjà utilisé la classe. Vous devez changer non seulement la classe Cercle, mais aussi les programmes qui l’utilisent.

Pour éviter des modifications directes des attributs d’instance, ne laissez pas l’utilisateur y accède directement.
Ceci est connu comme masquage de données. Il peut être effectué en définissant des attributs privés. En Python, les attributs privés commencent par deux caractères de soulignement « _ ».

Les attributs privés sont accessibles à l’intérieur de la classe seulement. En effet, ils ne sont pas accessibles en dehors de la classe.

Pour permettre la consultation de la valeur d’un attribut d’instance, vous pouvez fournir une méthode renvoyant la valeur de l’attribut.

En plus, vous pouvez fournir aussi une méthode permettant de modifier un attribut privé afin de pouvoir changer sa valeur sans y accéder directement.

Dans le code ci-dessous, la méthode ObtenirRayon() permet d’obtenir la valeur du rayon defini en tant qu’attribut privé de la classe Cercle. D’autre part, la méthode ChangerRayon() permet à l’utilisateur de changer la valeur du rayon d’une manière indirecte.

>>>class Cercle()
   def __init__(self, r=1):
      self.__rayon=r

   def ObtenirRayon(self):
      return __rayon

   def ChangerRayon(self,r):
      __rayon=r

>>> c = Circle(5)
>>>c.__rayon
AttributeError: no attribute '__rayon'
>>>c.ObtenirRayon()
5
>>>c.ChangerRayon(6)
>>>c.ObtenirRayon()
6
>>>

Comme indiqué dans le script ci-dessus, on n’a pas pu accéder à l’attribut __rayon et afficher sa valeur car il est déclaré privé.

Attributs de classe et méthodes statiques

Les classes peuvent être utilisées comme des sortes de modules. Nous allons voir qu’il est possible d’y définir des variables et des fonctions qui pourront être utilisés comme ce que vous aviez fait jusqu’à maintenant avec des modules.

Attributs de classe

Tout d’abord, il est possible de définir des attributs de classe qui ne seront pas associés à une instance en particulier mais à toute la classe. Toutes les instances partageront donc cet attribut. Pour créer de tels attributs, il suffit de les déclarer directement dans une classe.

class Test :
   variableTest = 0

En faisant cela, on crée une variable globale au sein de la classe Test. Il est possible d’accéder à ce type d’attributs soit via la classe soit via une instance. Mais attention, d’une instance sur l’autre, la variable sera exactement la même ! Faisons un petit essai en shell.

>>>class Test :
   variable = 0

>>> t = Test()
>>>Test.variable
0
>>>t.variable
0
>>>Test.variable += 1
>>>t.variable
1
>>>Test.variable
1

Je déclare ici ma classe de test. J’instancie cette classe puis accède à la variable de classe via la classe puis via une instance. Vous pouvez remarquer qu’ensuite je modifie la valeur de cette variable en y accédant via la classe mais la valeur est bel et bien modifiée aussi pour l’instance ! C’est donc bien un attribut de classe !

En permettant l’accès des attributs de classe via une instance, Python crée une ambiguïté sur les noms des attributs de classe et d’instance. L’interpréteur ne pourra différencier ces deux types d’attributs ! Essayez donc de toujours donner des noms différents aux attributs de classe et aux attributs d’instance !

L’intérêt de ces attributs réside principalement dans la définition de constantes qui peuvent être utilisées dans la classe ou à l’extérieur. Un attribut de classe est un excellent moyen de proposer une liste de constantes correspondant à une liste de choix possibles. Mais ces attributs peuvent aussi être utilisés pour donner la version du programme, compter le nombre d’instances créées et encore bien d’autres choses!

Méthodes statiques

Les méthodes statiques ne prennent aucun argument obligatoire. Leur déclaration est relativement similaire aux méthodes d’instance puisque la seule différence réside dans le fait de ne pas prendre comme argument l’instance courante ainsi que appeler la fonction intégrée staticmethod().

class Test :
   def fonction() :
      print("Je suis une fonction statique !")

   fonction = staticmethod(fonction)



Test.fonction()
t = Test()
t.fonction()

Avec cet exemple, vous pouvez constater que les deux types d’appels fonctionnent. Par contre, une classe ne peut appeler une fonction d’instance. La seule différence est donc bien dans le fait que les méthodes statiques ne prennent pas pour premier argument une classe.

Avec les attributs et les méthodes statiques, vous pouvez faire de vos classes de véritables modules! Cela vous permet ainsi de créer des ensembles cohérents de données et de fonctions tous organisés autour d’un même thème représenté par la classe.

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here