Une classe permet de créer sa propre structure de données personnalisée en regroupant des données (attributs) et des fonctions (méthodes) qui opèrent sur ces données.
Une classe définit un type d’objet
On crée des instances de la classe (des objets concrets)
Chaque instance possède ses propres attributs (variables)
Les méthodes sont des fonctions associées à la classe
Définir une classe
Pour définir une classe, on utilise le mot-clé class suivi du nom de la classe (par convention en majuscule).
# Définir une classeclass Etudiant:pass# Créer une instancee1 = Etudiant()print(Etudiant, type(Etudiant), sep='\n')print('\n'+'*'*20+'\n')print(e1, type(e1), sep='\n')
Les méthodes sont des fonctions définies à l’intérieur d’une classe. Le premier paramètre d’une méthode est toujours self, qui représente l’instance elle-même.
Remarque. Lors de l’appel d’une méthode, Python passe automatiquement l’instance comme premier argument. On n’écrit donc pas e1.se_presenter(e1) mais simplement e1.se_presenter() (comme nous l’avons vu avec les méthodes de liste, telles que append).
class Etudiant:def se_presenter(self):print('Bonjour!')e1 = Etudiant()e1.se_presenter()
Bonjour!
class Etudiant:def se_presenter(self):print('Bonjour, je suis', self)e1 = Etudiant()e1.se_presenter()
Bonjour, je suis <__main__.Etudiant object at 0x7a269a8da440>
Le constructeur __init__
Le constructeur__init__ est une méthode spéciale appelée automatiquement lors de la création d’une instance. Elle permet (entre autre) d’initialiser des attributs de l’instance.
Un attribut est une variable attachée à une instance spécifique d’une classe (par exemple, self.nom et self.age).
class Etudiant:def__init__(self, n, a):self.nom = nself.age = adef se_presenter(self):print('Bonjour!')e1 = Etudiant('Poirot', 20)print('Nom :', e1.nom)print('Age :', e1.age)
Nom : Poirot
Age : 20
# Avec valeurs par défautclass Etudiant:def__init__(self, n, a=18):self.nom = nself.age = ae1 = Etudiant('Poirot')e2 = Etudiant('Hastings', 22)print(e1.nom, e1.age)print(e2.nom, e2.age)
Poirot 18
Hastings 22
Remarque. Chaque instance possède ses propres attributs. Modifier l’attribut d’une instance n’affecte pas les autres instances.
class Etudiant:def__init__(self, n, a):self.nom = nself.age = ae1 = Etudiant('Poirot', 20)print('Age initial:', e1.age)# Modification de l'attribute1.age +=1print('Nouvel age:', e1.age)
Age initial: 20
Nouvel age: 21
Inspecter les attributs : vars
La fonction vars permet d’inspecter tous les attributs d’une instance sous forme de dictionnaire.
Remarque. La fonction dir renvoie tous les noms disponibles sur un objet (attributs et méthodes), y compris les méthodes spéciales entourées de __ (comme init, str) que Python invoque automatiquement.
Par défaut, print(instance) affiche une représentation peu lisible. On peut personnaliser cet affichage en définissant la méthode spéciale __str__ qui doit retourner une chaîne de caractères.
class Etudiant:def__init__(self, n, a):self.nom = nself.age = adef__str__(self):returnself.nom +', '+str(self.age) +' ans'e1 = Etudiant('Poirot', 20)print(e1)
Poirot, 20 ans
Exemple final : plusieurs classes
Voici un exemple complet avec deux classes qui interagissent:
Livre
class Livre:def__init__(self, titre, auteur, pages):self.titre = titre self.pages = pagesself.auteur = auteurself.progression =0def__str__(self): pct =str(int(self.progression *100))return (self.titre +' par '+self.auteur +', '+str(self.pages) +' pages, lu à '+ pct +'%')def lire(self, nb_pages): debut =self.progression *self.pagesself.progression =min((debut + nb_pages) /self.pages, 1)
Biblio
class Biblio:def__init__(self, L, propriétaire):self.contenu = [livre for livre in L iftype(livre) == Livre]self.propriétaire = propriétairedef livre_par_auteur(self, auteur):return [livre for livre inself.contenu if livre.auteur == auteur]def grouper_par_auteur(self): d = {}for livre inself.contenu:if livre.auteur in d: d[livre.auteur].append(livre)else: d[livre.auteur] = [livre]return ddef acheter_livre(self, livre):self.contenu.append(livre)def prêter_livre(self, livre):self.contenu.remove(livre)def__str__(self):return ('La bibliothèque de '+self.propriétaire +'. Elle contient '+str(len(self.contenu)) +' livres.')def afficher_livres(self):for livre inself.contenu:print(livre)
Acheter plein de livres
from fonctions_ics import get_random_bookb = Biblio([], 'Leonard')n =100for i inrange(n): titre, auteur, pages = get_random_book() livre = Livre(titre, auteur, pages) b.acheter_livre(livre)print(i, '/ '+str(n))print(b)print('\nPremiers livres:')for livre in b.contenu[:5]:print(livre)
Voici la bibliothèque de Leonard. Elle contient 100 livres.
Premiers livres: Stones from the River par Ursula Hegi, 334 pages, lu à 0% Mad Dogs (Cherub, #8) par Robert Muchamore, 421 pages, lu à 0% Ruin and Rising (Shadow and Bone, #3) par Leigh Bardugo, 169 pages, lu à 0% Neverwhere par Neil Gaiman, 340 pages, lu à 0% Their Eyes Were Watching God par Zora Neale Hurston, 320 pages, lu à 0%