Cours de Python - Modularisation

version 1.1.1, dernière mise à jour le 28 octobre 2021.

   

Table des matières (TdM)

  1. I. Import de modules
    1. Principe
    2. Importation avec nommage
      1. Exercice : Importation
  1. II. Programmation orientée objet : classes et objets
    1. Principes de la programmation orientée objet
      1. Introduction
      2. Qu'est-ce qu'un objet ?
      3. Qu'es-ce qu'une classe?
    2. Classe et objet simple
      1. Définition d'une classe minimale
      2. Ajout de propriétés
      3. Ajout de de méthodes
      4. Exercice : Une classe simple
      5. Exercice : Définition d'une classe avec méthode
      6. Exercice : Classe avec valeurs par défaut
    3. Constructeur
      1. Exercice : Classe avec constructeur et valeurs par défaut
      2. Exercice : Définition d'une classe avec constructeur
    4. Encapsulation
      1. Exercice : Définition d'une classe avec propriété privée
    5. Héritage
    6. Exercice : Héritage

Retour au menu

Contenu du cours

I. Import de modules

1. Principe

Il est tout à fait possible de se créer des bibliothèques de fonctions pour éviter de dupliquer un travail déjà fait dans le cadre d'un projet, ou bien pour pouvoir réutiliser des fonctions ou des définitions de classes (voir ci-après) dans des projets différents.

Pour cela, il faut simplement écrire la liste des fonctions dans un fichier .py (par exemple mes_fonctions.py) puis importer ce fichier avant toute autre opération dans le code, avec les mots-clefs from... import (dans ce cas, from mes_fonctions import *). Cette syntaxe comporte plusieurs variantes :

>Retour à la TdM

2. Importation avec nommage

Afin d'éviter d'éventuels conflits de noms (par exemple quand deux fonctions portent le même nom dans deux fichiers différents), d'une manière similaire aux espaces de noms XML, on peut expliciter un préfixe pour le module importé :

Exercice 1. Importation

Énoncé
Correction (Fonctions d'addition et de soustraction)
Correction (Fonctions de multiplication et de division)
Correction (Importation sans nommage)
Correction (Importation avec nommage)

>Retour à la TdM

II. Programmation orientée objet : classes et objets

1. Principes de la programmation orientée objet

a. Introduction

Il n'est pas dans le propos de ce cours de faire une initiation complète à la Programmation Orientée Objet, mais d'en présenter les quelques points qui sont utiles au jour le jour en Python.

b. Qu'est-ce qu'un objet ?

Un objet est une entité de programmation qui possèdent un certain nombre de propriétés, et sur laquelle il est possible d'agir ou qui est susceptible d'agir par l'intermédiaire de méthodes. Une méthode est une sorte de fonction s'appliquant à l'objet, et à la syntaxe un peu particulière.

Une propriété caractérise un objet. Par exemple, si l'on pense à un objet physique comme une boîte, ses propriétés pourraient être ses longueur, hauteur et profondeur, sa couleur, le fait qu'elle soit ouverte ou fermée, pleine ou vide, etc. Des méthodes permettant d'interagir avec cette boîte seraient par exemple l'action de l'ouvrir ou de la fermer (qui agirait sur la propriété « ouverte ou fermée »), celle d'y ajouter ou d'en extraire du contenu (qui agirait sur la propriété « pleine ou vide »), etc. En Python comme dans les autres langages orientés objet, on représente les propriétés et les méthodes avec des points. Pour reprendre notre exemple de boîte, une implémentation Python en serait :

boite.longueur
boite.hauteur
boite.profondeur
boite.couleur
boite.ouverte
boite.pleine

boite ouvrir()
boite fermer()
boite remplir(contenu) ;
boite vider()

c. Qu'es-ce qu'une classe?

Une étape supplémentaire de conceptualisation d'un objet passe par la définition d'une classe. Une classe est une représentation abstraite d'une entité ; en tant que telle, elle n'a pas d'existence mais sert à définir des objets, qui en sont des instances. Par exemple, dans le monde physique on peut définir une classe que l'on nommera Gant. Cette classe, conçue pour pouvoir décrire n'importe quel type de livre, possède des méthodes et des propriétés, par exemple une méthode retourner(), et des propriétés couleur, matière et sens. Mais le concept de gant en lui-même n'a pas de couleur ni de matière ; seul a une couleur un gant particulier, qui sera fabriqué en laine par exemple. Dans ce cas, on appelle classe la définition de toutes les propriétés et méthodes qu'un gant doit avoir, et instanciation les propriétés et méthodes d'un gant en particulier.

>Retour à la TdM

2. Classe et objet simple

a. Définition d'une classe minimale

La définition d'une classe est tout à fait simulaire à celle d'une fonction. Par convention, on a l'habitude de mettre une majuscule à la première lettre du nom d'une classe.

class ExempleClasse:
  """Documentation de la classe"""
  #Définition de la classe

p = ExempleClasse()

Les """ après le nom de la classe servent à la documentation. p est une instanciation de la classe. Attention à cette étape à la duplication d'objets :

p1=ExempleClasse()
p2=ExempleClasse()
p3=p1
print(p1)
<__main__.ExempleClasse object at 0x7ff404091ba8>
print(p2)
<__main__.ExempleClasse object at 0x7ff404091b70>
print(p3)
<__main__.ExempleClasse object at 0x7ff404091ba8>

On remarque dans le code précédent que les variables p1 et p3 renvoient bien au même objet, à l'adresse mémoire 0x7ff404091ba8.

Pour le moment, une telle classe est vide, et les objets qui l'instancient aussi.

b. Ajout de propriétés

On peut ensuite ajouter des propriétés à l'objet ainsi créé. On définit ainsi une nouvelle propriété x :

p1.x="valeur de x"

c. Ajout de de méthodes

La définition de méthodes se fait en revanche lors de la définition de la classe, et de manière similaire à une définition de fonction, à un détail près :

class ExempleClasse:
  def methode1 (self, a,b):
    self.x=2*a
    self.y=2*a*b

Le mot-clef self est en effet obligatoire et doit apparaître comme premier argument.

On peut ensuite instancier la classe ExempleClasse, puis utiliser la méthode methode1 pour créer les deux propriétés x et y de l'objet instancié :

test = ExempleClasse()
test.methode1(2,3)
print(test.x, test.y)

L'exemple précédent affiche 4 et 12.

On peut d'ailleurs tout à fait définir des valeurs par défaut, de la même manière que pour les fonctions :

class exempleClasse:
  def methode1(self, a=3,b=8):
    self.x=2*a
    self.y=2*a*b

Exercice 1. Une classe simple

Énoncé
Correction

Exercice 2. Définition d'une classe avec méthode

Énoncé
Correction

Exercice 3. Classe avec valeurs par défaut

Énoncé
Correction

>Retour à la TdM

3. Constructeur

En programmation orientée objet, le constructeur permet de « construire » un nouvel objet à partir d'une classe, en lui passant des paramètres. Jusqu'à présent en effet, quand nous écrivions nouvelObjet = ExempleClasse(), le nouvel objet ne possédait pas de propriété prédéfinie. Un constructeur le permet.

En Python, le constructeur est une méthode portant un nom prédéfini et réservé, __init__ (commençant et finissant par deux « underscores »). Comme toute méthode, le constructeur peut accepter des paramètres, avec ou sans valeur par défaut. Par exemple…

class Test:
  def __init__ (self, t=4, z=5):
    self.x="varx"
    self.y="vary"
    self.t=t
    self.z=z

nouvelObjet0=Test()
nouvelObjet1=Test(z=3)

print(nouvelObjet0.x, nouvelObjet0.y, nouvelObjet0.t, nouvelObjet0.z)
print(nouvelObjet1.x, nouvelObjet1.y, nouvelObjet1.t, nouvelObjet1.z)

Ce code affiche varx vary 4 5 puis varx vary 4 3.

Exercice 1. Classe avec constructeur et valeurs par défaut

Énoncé
Correction

Exercice 2. Définition d'une classe avec constructeur

Énoncé
Correction

>Retour à la TdM

4. Encapsulation

L'encapsulation consiste en le masquage de certaines propriétés afin qu'elles ne soient plus directement accessibles depuis l'extérieur de l'objet. Pour définir une propriété privée, on préfixe son nom, encore une fois, par deux « underscores » dans le constructeur :

class ClasseTest :

  #Constructeur
    def __init__ (self):
      self.a=1
      self.b=2
      self.__c=3
      self.__d=4

  #getters
    def get_a(self):
      return self.a
    def get_b(self):
      return self.b
    def get_c(self):
      return self.__c
    def get_d(self):
      return self.__d

  #setters
    def set_a(self, x):
      self.a=x
    def set_b(self, x):
      self.b=x
    def set_c(self, x):
      self.__c=x
    def set_d(self, x):
      self.__d=x

test=ClasseTest()

Dans l'exemple précédent, les propriétés test.a et test.b sont accessibles directement, mais print(test.c) renvoie un message d'erreur, car la propriété est introuvable.

Exercice 1. Définition d'une classe avec propriété privée

Énoncé
Correction

>Retour à la TdM

5. Héritage

En programmation orientée objet, l'héritage est la possibilité pour une classe de dériver d'une classe déjà existante, en en récupérant propriétés et méthodes, tout en lui ajoutant d'autres. Pour cela, il suffit d'indiquer :

Par exemple :

class Parente :
  """Classe parente"""

  def __init__(self):
    self.__prop1=1
    self.__prop2=2

  def get_prop1(self):
    return self.__prop1
  def get_prop2(self):
    return self.__prop2

  def set_prop1(self, x):
    self.__prop1=x
  def set_prop2(self, x):
    self.__prop2=x

class Enfant(Parente) :
  """Classe enfant"""

  def __init__(self):
    Parente.__init__(self)
    self.__prop3=3

  def get_prop3(self):
    return self.__prop3
  def set_prop3(self, x):
    self.__prop3=x

>Retour à la TdM

Exercice 1. Héritage

Énoncé
Correction

Historique de ce document

Conditions d'utilisation et licence

Creative Commons License
Cette création est mise à disposition par Gilles Chagnon sous un contrat Creative Commons.

Retour au menu