Programmation orientée objet en Python Nicolas Pronost Philosophie de la POO •
Programmation orientée objet en Python Nicolas Pronost Philosophie de la POO • Dans la programmation orientée objet (POO), toutes les variables sont des objets associés à une classe • Une classe est un type • qui se veut plus complexe que juste un nombre ou un caractère • Un objet est une collection • de données membres (ou attributs) • de fonctions membres manipulant les données membres (ou méthodes) • On peut créer autant d’objets de classe (i.e. de variables du type décrit par la classe) que l’on veut • Un objet est aussi appelé une instance de classe • En Python, tout est objet 2 Définition d’une classe • Pour définir une classe on utilise le mot clé class • On peut ensuite ajouter des données membres et des fonctions membres • fontionMembre est une fonction membre que l’on peut appeler sur une instance de la classe MaClasse 3 class MaClasse : '''Documentation brève de la classe''' class MaClasse : '''Documentation brève de la classe''' def fonctionMembre(self) : print('Hello') Création d’un objet • On peut créer une instance (ou objet) de classe en utilisant le nom de la classe suivie de parenthèses • On peut ensuite accéder aux données membres et fonctions membres en utilisant l’opérateur . (point) 4 uneInstance = MaClasse() uneInstance.fonctionMembre() #affiche 'Hello' Référence à l’instance • Vous avez noter la présence du paramètre self dans la fonction membre • Pourtant il n’est pas passé en paramètre lors de l’appel • Lorsqu’une fonction membre est appelée sur une instance de classe, cette instance est automatiquement ajoutée en tant que premier paramètre • L’appel est traduit automatiquement en 5 def fontionMembre (self) : uneInstance.fonctionMembre() uneInstance.fontionMembre() MaClasse.fonctionMembre(uneInstance) Référence à l’instance • Cela veut aussi dire, que toute fonction membre d’une classe a au moins un paramètre : l’instance • Par convention on le nomme self • A l’intérieur de la fonction membre, self désigne l’instance sur laquelle la fonction est appelée, on peut donc l’utiliser pour accéder aux données membres et aux fonctions membres spécifiques à cette instance 6 class MaClasse : donneeCommune = 0 def fctSurInstance (self) : self.donneeInstance = 1 MaClasse.donneeCommune += 1 instance1 = MaClasse() # dC = 0 , i1.dI n’existe pas instance1.fctSurInstance() # dC = 1 , i1.dI = 1 instance2 = MaClasse() # dC = 1 , i2.dI n’existe pas instance2.fctSurInstance() # dC = 2 , i2.dI = 1 Membres spéciaux • Les données et fonctions qui commencent par un double tiret-bas (__) sont des membres spéciaux, ils ont un sens particulier • Il existe plusieurs données membres spéciales dont • __doc__ : documentation de la classe (donnée par la docstring, i.e. le texte entre ''' en dessous du nom de la classe) • __name__ : nom de la classe • __dict__ : dictionnaire où les clés sont les noms des données membres et les valeurs sont les valeurs des données membres 7 Constructeur • Parmi les fonctions membres spéciales, il y a le constructeur de la classe • Il porte le nom suivant : __init__ • Cette fonction est appelée quand une instance de la classe est créée • elle renvoie l’objet (self) après création 8 Constructeur • Le constructeur est habituellement utilisé pour initialiser les valeurs des données membres • Il prend donc habituellement les valeurs des données membres à donner à cette instance en paramètre 9 class NombreComplexe : def __init__ (self,r,i) : self.Re = r self.Im = i nc = NombreComplexe(2,4) class NombreComplexe : def __init__ (self) : self.Re = 0 self.Im = 0 nc = NombreComplexe() Création à la volée • Rappeler vous que Python est un langage interprété, donc il est capable d’ajouter des données membres à la volée • Il peut aussi en supprimer (instruction del) • cela fonctionne sur les données membres, sur les fonctions membres et sur les instances elles-mêmes 10 nc1 = NombreComplexe() nc2 = NombreComplexe() #création à la volée d’une donnée membre texte pour nc1 nc1.texte = 'ceci est un nombre complexe' print(nc2.texte) # produit une erreur (pas de membre nommé texte dans nc2) nc1 = NombreComplexe() del nc1.Im Fonctions membres d’une classe • On a vu des données membres de classe (communes aux instances), des données membres d’instance (spécifiques à une instance) et des fonctions membres d’instances (avec le paramètre self) • Il existe la possibilité, plus rarement utilisée, d’avoir des fonctions membres de classe (communes aux instances) • le premier paramètre s’appelle alors cls (pour classe) • on indique à Python que c’est une fonction de classe grâce à la fonction classmethod • on l’appelle avec l’opérateur . (point) sur la classe (comme pour les données membres de la classe) ou sur une des instances de la classe 11 Fonctions membres d’une classe 12 class NombreComplexe : nbComplexesCrees = 0 def __init__ (self) : self.Re = 0 self.Im = 0 NombreComplexe.nbComplexeCrees += 1 def afficheNbComplexe (cls) : print(NombreComplexe.nbComplexeCrees) afficheNbComplexe = classmethod(afficheNbComplexe) NombreComplexe.afficheNbComplexe() # affiche 0 nc1 = NombreComplexe() NombreComplexe.afficheNbComplexe() # affiche 1 nc2 = NombreComplexe() NombreComplexe.afficheNbComplexe() # affiche 2 # on peut aussi faire : nc2.afficheNbComplexe() Destructeur • Parmi les fonctions spéciales, il y a aussi le destructeur de la classe • Il porte le nom suivant : __del__ • Cette procédure est appelée • lorsque vous demander vous-même la destruction • automatiquement en sortant de la porté de l’objet • Le destructeur est habituellement utilisé pour effectuer des actions avant la destruction de l’objet 13 del nc1 class NombreComplexe : def __init__ (self) : self.Re = 0 self.Im = 0 def __del__ (self) : print("Un nombre complexe a été détruit") Représentation d’un objet • Un simple print sur l’objet affiche ce type d’information • Pas très utile... • Deux fonctions membres spéciales permettent de contrôler comment l’objet est représenté et affiché à l’écran 14 nc1 = NombreComplexe() print(nc1) # affiche quelque chose comme : # <__main__.NombreComplexe object at 0x00AC45B70> Représentation d’un objet • La fonction membre spéciale __repr__ retourne la chaîne de caractère qu’il faut afficher lorsque l’on tape directement le nom de l’objet (plutôt pour le debug) 15 class NombreComplexe : def __init__ (self,r,i) : self.Re = r self.Im = i def __repr__ (self) : if self.Im >= 0 : return str(self.Re) + '+' + str(self.Im) + 'i' else : return str(self.Re) + str(self.Im) + 'i' nc1 = NombreComplexe(5,2) nc2 = NombreComplexe(5,-2) nc1 # affiche 5+2i nc2 # affiche 5-2i Représentation d’un objet • La fonction membre spéciale __str__ retourne la chaîne de caractère qu’il faut afficher lorsque l’on appelle la fonction print sur l’objet 16 class NombreComplexe : def __init__ (self,r,i) : self.Re = r self.Im = i def __str__ (self) : if self.Im >= 0 : return str(self.Re) + '+' + str(self.Im) + 'i' else : return str(self.Re) + str(self.Im) + 'i' nc1 = NombreComplexe(5,2) print(nc1) # affiche 5+2i Surcharge d’opérateur • Une fois que vous avez défini une classe (i.e. un type), vous voulez pouvoir manipuler facilement les instances de cette classe • Comme vous le faîtes déjà avec les types de base: ex. faire des opérations mathématiques entre deux entiers, accéder à un élément d’une liste etc. • Il existe un moyen de spécifier ces opérations dans une classe sans avoir à inventer des noms de fonction • ça serait dommage d’avoir à faire • si on pouvait faire • par contre, il faut décider de ce que veut dire par faire l’addition de deux nombres complexes, l’ordinateur ne peut pas décider pour vous 17 nc3 = nc1.additionnerAvec(nc2) nc3 = nc1 + nc2 Surcharge d’opérateur 18 class NombreComplexe : def __init__ (self,r,i) : self.Re = r self.Im = i def __add__ (self, operandeDroite) : resultat = NombreComplexe(self.Re,self.Im) resultat.Re += operandeDroite.Re resultat.Im += operandeDroite.Im return resultat nc1 = NombreComplexe(5,2) nc2 = NombreComplexe(-1,1) nc3 = nc1 + nc2 # nc3 représente le complexe 4+3i Surcharge d’opérateur • Vous pouvez ainsi surcharger la plupart des opérations mathématiques • __sub__ pour la soustraction (-) • __mul__ pour la multiplication (*) • __truediv__ pour la division (/) • __floordiv__ pour la division entière (//) • __mod__ pour le modulo (%) • __pow__ pour la puissance (**) • etc. • Vous pouvez surcharger les opérateurs combinés • __iadd__ pour l’addition avec affectation (+=) • __isub__ pour la soustraction avec affectation (-=) • etc. 19 Surcharge d’opérateur • Les opérateurs de comparaison peuvent aussi être surchargés • __eq__ pour la comparaison (==) • __ne__ pour la différence (!=) • __gt__ pour la supériorité stricte (>) • __ge__ pour la supériorité (>=) • __lt__ pour l’infériorité stricte (<) • __le__ pour l’infériorité (<=) • Exemple 20 class NombreComplexe : def __init__ (self,r,i) : self.Re = r self.Im = i def __eq__ (self, nc) : return self.Re == nc.Re and self.Im == nc.Im nc1 = NombreComplexe(5,2) nc2 = NombreComplexe(-1,1) estEgal = (nc1 == nc2) # estEgal vaut False Surcharge d’opérateur • Les opérateurs logiques aussi • __and__ pour le ET logique • __or__ pour le OU logique • __xor__ pour le OU EXCLUSIF logique • __invert__ pour la NEGATION (~) • Exemple 21 class NombreComplexe : def __init__ (self,r,i) : self.Re = r uploads/s1/04-programmation-orientee-objet.pdf
Documents similaires
-
44
-
0
-
0
Licence et utilisation
Gratuit pour un usage personnel Attribution requise- Détails
- Publié le Fev 03, 2021
- Catégorie Administration
- Langue French
- Taille du fichier 0.9395MB