La programmation est un art. Et comme dans l’art, le choix des pinceaux et des peintures appropriés est essentiel pour produire les meilleures œuvres. La programmation orientée objet de Python est l’une de ces compétences.

Le choix du bon langage de programmation est un élément crucial de tout projet. Il peut conduire soit à un développement fluide et agréable, soit à un véritable cauchemar. Il serait donc préférable que vous utilisiez le langage le mieux adapté à votre cas d’utilisation.

C’est la principale raison d’apprendre la programmation orientée objet dans Python, qui est aussi l’un des langages de programmation les plus populaires.

Apprenons !

Un exemple de programme Python

Avant d’entrer dans le vif du sujet, posons une question : avez-vous déjà écrit un programme Python comme celui qui suit ?

secret_number = 20
 
while True:
   number = input('Guess the number: ')
 
   try:
       number = int(number)
   except:
       print('Sorry that is not a number')
       continue
 
   if number != secret_number:
       if number > secret_number:
           print(number, 'is greater than the secret number')
 
       elif number < secret_number:
           print(number, 'is less than the secret number')
   else:
       print('You guessed the number:', secret_number)
       break

Ce code est un simple devineur de nombres. Essayez de le copier dans un fichier Python et de l’exécuter dans votre système. Il remplit parfaitement son rôle.

Mais voici un énorme problème : que se passerait-il si nous vous demandions d’implémenter une nouvelle fonctionnalité ? Cela pourrait être quelque chose de simple – par exemple :

« Si l’entrée est un multiple du nombre secret, donner un indice à l’utilisateur. »

Le programme deviendrait rapidement complexe et lourd au fur et à mesure que vous augmentez le nombre de fonctionnalités et, par conséquent, le nombre total de conditionnels imbriqués.

C’est précisément le problème que la programmation orientée objet tente de résoudre.

Pré-requis pour apprendre Python POO

Avant de vous lancer dans la programmation orientée objet, nous vous recommandons vivement de maîtriser les bases de Python.

Il peut être difficile de classer les sujets considérés comme « basiques ». C’est pourquoi nous avons conçu un aide-mémoire reprenant les principaux concepts nécessaires à l’apprentissage de la programmation orientée objet dans Python.

  • Variable : Nom symbolique qui pointe vers un objet spécifique (nous verrons ce que signifient les objets au fil de l’article).
  • Opérateurs arithmétiques : Addition (+), soustraction (-), multiplication (*), division (/), division entière (//), modulo (%).
  • Types de données intégrés : Numériques (entiers, flottants, complexes), Séquences (chaînes de caractères, listes, tuples), Booléens (Vrai, Faux), Dictionnaires et Ensembles.
  • Expressions booléennes : Expressions dans lesquelles le résultat est True ou False.
  • Conditionnel : Évalue une expression booléenne et effectue un traitement en fonction du résultat. Géré par les instructions if/else.
  • Boucle : Exécution répétée de blocs de code. Il peut s’agir de boucles for ou while.
  • Fonctions : Bloc de code organisé et réutilisable. On les crée avec le mot-clé def.
  • Arguments : Objets passés à une fonction. Par exemple : sum([1, 2, 4])
  • Exécuter un script Python : Ouvrir un terminal ou une ligne de commande et saisir « python <nom du fichier> ».
  • Ouvrir un shell Python : Ouvrir un terminal et saisir python ou python3 selon votre système.

Maintenant que ces concepts sont clairs comme de l’eau de roche, vous pouvez passer à la compréhension de la programmation orientée objet.

Qu’est-ce que la programmation orientée objet dans Python ?

La programmation orientée objet (POO) est un paradigme de programmation dans lequel nous pouvons considérer des problèmes complexes comme des objets.

Un paradigme est une théorie qui fournit la base de la résolution des problèmes.

Ainsi, lorsque nous parlons de POO, nous faisons référence à un ensemble de concepts et de modèles que nous utilisons pour résoudre des problèmes avec des objets.

Dans Python, un objet est une collection unique de données (attributs) et de comportements (méthodes). Vous pouvez considérer les objets comme des choses réelles qui vous entourent. Prenons l’exemple des calculatrices :

Une calculatrice peut être un objet.
Une calculatrice peut être un objet.

Comme vous pouvez le remarquer, les données (attributs) sont toujours des noms, tandis que les comportements (méthode) sont toujours des verbes.

Cette compartimentation est le concept central de la programmation orientée objet. Vous construisez des objets qui stockent des données et contiennent des types de fonctionnalités spécifiques.

Pourquoi utilisons-nous la programmation orientée objet dans Python ?

La POO vous permet de créer des logiciels sûrs et fiables. De nombreux frameworks et bibliothèques Python utilisent ce paradigme pour construire leur base de code. Quelques exemples sont Django, Kivy, pandas, NumPy, et TensorFlow.

Voyons les principaux avantages de l’utilisation de la POO dans Python.

Avantages de la POO de Python

Les raisons suivantes vous feront opter pour l’utilisation de la programmation orientée objet dans Python.

Tous les langages de programmation modernes utilisent la POO

Ce paradigme est indépendant du langage. Si vous apprenez la POO dans Python, vous serez en mesure de l’utiliser dans les cas suivants :

Tous ces langages sont soit nativement orientés objet, soit incluent des options pour des fonctionnalités orientées objet. Si vous souhaitez apprendre l’un d’entre eux après Python, ce sera plus facile – vous trouverez de nombreuses similitudes entre les langages travaillant avec des objets.

La POO vous permet de coder plus rapidement

Coder plus rapidement ne signifie pas écrire moins de lignes de code. Cela signifie que vous pouvez implémenter plus de fonctionnalités en moins de temps sans compromettre la stabilité d’un projet.

La programmation orientée objet vous permet de réutiliser du code en mettant en œuvre l’abstraction. Ce principe rend votre code plus concis et plus lisible.

Comme vous le savez peut-être, les programmeurs passent beaucoup plus de temps à lire le code qu’à l’écrire. C’est la raison pour laquelle la lisibilité est toujours plus importante que la sortie des fonctionnalités le plus rapidement possible.

La productivité diminue lorsque le code n'est pas lisible
La productivité diminue lorsque le code n’est pas lisible

Vous en saurez plus sur le principe d’abstraction plus tard.

La POO vous aide à éviter le code spaghetti

Vous vous souvenez du programme de devinette des chiffres présenté au début de cet article ?

Si vous continuez à ajouter des fonctionnalités, vous aurez à l’avenir de nombreuses instructions if imbriquées. Cet enchevêtrement de lignes de code sans fin est appelé code spaghetti, et vous devez l’éviter autant que possible.

La POO nous donne la possibilité de compresser toute la logique dans des objets, évitant ainsi les longs morceaux de if imbriqués.

La POO améliore votre analyse de toute situation

Une fois que vous aurez acquis une certaine expérience de la POO, vous serez en mesure de considérer les problèmes comme des objets petits et spécifiques.

Cette compréhension conduit à une initialisation rapide du projet.

Programmation structurée et programmation orientée objet

La programmation structurée est le paradigme le plus utilisé par les débutants car c’est la manière la plus simple de construire un petit programme.

Il s’agit d’exécuter un programme Python de manière séquentielle. Cela signifie que vous donnez à l’ordinateur une liste de tâches et que vous les exécutez de haut en bas.

Voyons un exemple de programmation structurée avec le programme d’un café.

small = 2
regular = 5
big = 6
 
user_budget = input('What is your budget? ')
 
try:
   user_budget = int(user_budget)
except:
   print('Please enter a number')
   exit()
 
if user_budget > 0:
   if user_budget >= big:
       print('You can afford the big coffee')
       if user_budget == big:
           print('It\'s complete')
       else:
           print('Your change is', user_budget - big)
   elif user_budget == regular:
       print('You can afford the regular coffee')
       print('It\'s complete')
   elif user_budget >= small:
       print('You can buy the small coffee')
       if user_budget == small:
           print('It\'s complete')
       else:
           print('Your change is', user_budget - small)

Le code ci-dessus agit comme un vendeur de café. Il vous demandera un budget, puis vous « vendra » le plus grand café que vous êtes capable d’acheter.

Essayez de l’exécuter dans le terminal. Il s’exécutera étape par étape, en fonction de votre entrée.

Ce code fonctionne parfaitement, mais nous avons trois problèmes :

  1. Il y a beaucoup de logique répétée.
  2. Il utilise de nombreuses conditionnelles if imbriquées.
  3. Il sera difficile à lire et à modifier.

La POO a été inventée comme une solution à tous ces problèmes.

Voyons le programme ci-dessus mis en œuvre avec la POO. Ne vous inquiétez pas si vous ne le comprenez pas encore. C’est seulement pour comparer la programmation structurée et la programmation orientée objet.

class Coffee:
        # Constructor
        def __init__(self, name, price):
                self.name = name
                self.price = float(price)
        def check_budget(self, budget):
                # Check if the budget is valid
                if not isinstance(budget, (int, float)):
                        print('Enter float or int')
                        exit()
                if budget < 0: print('Sorry you don\'t have money') exit() def get_change(self, budget): return budget - self.price def sell(self, budget): self.check_budget(budget) if budget >= self.price:
                        print(f'You can buy the {self.name} coffee')
                        if budget == self.price:
                                print('It\'s complete')
                        else:
                                print(f'Here is your change {self.get_change(budget)}$')

                        exit('Thanks for your transaction')

Note : Tous les concepts suivants seront expliqués plus en détail dans l’article.

Le code ci-dessus représente une classe nommée « Coffee ». Elle possède deux attributs – « name » et « price » – et ils sont tous deux utilisés dans les méthodes. La méthode principale est « sell », qui traite toute la logique nécessaire à la réalisation du processus de vente.

Si vous essayez d’exécuter cette classe, vous n’obtiendrez aucun résultat. Cela se produit principalement parce que nous ne faisons que déclarer le « modèle » pour les cafés, et non les cafés eux-mêmes.

Implémentons cette classe avec le code suivant :

small = Coffee('Small', 2)
regular = Coffee('Regular', 5)
big = Coffee('Big', 6)
 
try:
   user_budget = float(input('What is your budget? '))
except ValueError:
   exit('Please enter a number')
  
for coffee in [big, regular, small]:
   coffee.sell(user_budget)

Ici, nous créons des instances, ou objets café, de la classe « Coffee », puis nous appelons la méthode « sell » de chaque café jusqu’à ce que l’utilisateur puisse s’offrir n’importe quelle option.

Nous obtiendrons le même résultat avec les deux approches, mais nous pouvons bien mieux étendre la fonctionnalité du programme avec la POO.

Vous trouverez ci-dessous un tableau comparant la programmation orientée objet et la programmation structurée:

POO Programmation structurée
Plus facile à maintenir Difficile à maintenir
Approche Don’t Repeat Yourself (DRY) Code répété à de nombreux endroits
Petits morceaux de code réutilisés à de nombreux endroits Une grande quantité de code à quelques endroits
Approche par objet Approche par blocs de code
Plus facile à déboguer Plus difficile à déboguer
Grande courbe d’apprentissage Courbe d’apprentissage plus simple
Utilisé dans les grands projets Optimisé pour les programmes simples

Pour conclure la comparaison des paradigmes :

  • Aucun des deux paradigmes n’est parfait (la POO peut être écrasante à utiliser dans des projets simples).
  • Ce ne sont là que deux façons de résoudre un problème ; il en existe d’autres.
  • La POO est utilisée dans les grandes bases de code, tandis que la programmation structurée est principalement destinée aux projets simples.

Passons maintenant aux objets intégrés dans Python.

Tout est un objet dans Python

Nous allons vous dire un secret : vous utilisez la POO tout le temps sans vous en rendre compte.

Même en utilisant d’autres paradigmes dans Python, vous utilisez toujours des objets pour presque tout faire.

C’est parce que, dans Python, tout est un objet.

Rappelez-vous la définition d’un objet : Un objet dans Python est une collection unique de données (attributs) et de comportements (méthodes).

Cela correspond à n’importe quel type de données dans Python.

Une chaîne de caractères est un ensemble de données (caractères) et de comportements (upper(), lower(), etc…). Il en va de même pour les entiers, les flottants, les booléens, les listes et les dictionnaires.

Avant de poursuivre, rappelons la signification des attributs et des méthodes.

Attributs et méthodes

Les attributs sont des variables internes aux objets, tandis que les méthodes sont des fonctions qui produisent un certain comportement.

Faisons un exercice simple dans le shell Python. Vous pouvez l’ouvrir en saisissant python ou python3 dans votre terminal.

Shell Python
Shell Python

Maintenant, travaillons avec le shell Python pour découvrir les méthodes et les types.

>>> kinsta = 'Kinsta, Premium Application, Database, and Managed WordPress hosting'
>>> kinsta.upper()
'KINSTA, PREMIUM APPLICATION, DATABASE, AND MANAGED WORDPRESS HOSTING'

Dans la deuxième ligne, nous appelons une méthode de chaîne de caractères, upper(). Elle renvoie le contenu de la chaîne en majuscules. Cependant, elle ne modifie pas la variable d’origine.

>>> kinsta
'Kinsta, Premium Application, Database, and Managed WordPress hosting'

Examinons les fonctions utiles pour travailler avec des objets.

La fonction type() permet d’obtenir le type d’un objet. Le « type » est la classe à laquelle l’objet appartient.

>>> type(kinsta)
# class 'str'

La fonction dir() renvoie tous les attributs et méthodes d’un objet. Testons-la avec la variable kinsta.

>>> dir(kinsta)
['__add__', '__class__',  ........... 'upper', 'zfill']

Maintenant, essayez d’afficher certains des attributs cachés de cet objet.

>>> kinsta.__class__ # class 'str' e>

Cette fonction renvoie la classe à laquelle appartient l’objet kinsta. Nous pouvons donc dire que la seule chose que la fonction type renvoie est l’attribut __class__ d’un objet.

Vous pouvez expérimenter avec tous les types de données, en découvrant tous leurs attributs et méthodes directement sur le terminal. Vous pouvez en savoir plus sur les types de données intégrés dans la documentation officielle.

Votre premier objet dans Python

Une classe est comme un modèle. Elle vous permet de créer des objets personnalisés en fonction des attributs et des méthodes que vous définissez.

Vous pouvez l’imaginer comme un emporte-pièce que vous modifiez pour préparer les cookies parfaits (des objets, pas des cookies de suivi), avec des caractéristiques définies : Forme, Taille, et plus encore.

D’autre part, nous avons des instances. Une instance est un objet individuel d’une classe, qui possède une adresse mémoire unique.

Instances en Python
Instances dans Python

Maintenant que vous savez ce que sont les classes et les instances, définissons-en quelques-unes !

Pour définir une classe dans Python, vous utilisez le mot-clé class, suivi de son nom. Dans ce cas, vous allez créer une classe nommée Cookie.

Note : Dans Python, nous utilisons la convention des noms en majuscules pour nommer les classes.

class Cookie:
	pass

Ouvrez votre shell Python et saisissez le code ci-dessus. Pour créer une instance d’une classe, il suffit de saisir son nom et la parenthèse qui le suit. C’est le même processus que pour invoquer une fonction.

cookie1 = Cookie()

Félicitations – vous venez de créer votre premier objet dans Python ! Vous pouvez vérifier son id et son type avec le code suivant :

id(cookie1)
140130610977040 # Unique identifier of the object

type(cookie1)
<class '__main__.Cookie'>

Comme vous pouvez le voir, ce cookie a un identificateur unique en mémoire, et son type est Cookie.

Vous pouvez également vérifier si un objet est une instance d’une classe avec la fonction isinstance().

isinstance(cookie1, Cookie)
# True
isinstance(cookie1, int)
# False
isinstance('a string', Cookie)
# False

Méthode constructor

La méthode __init__() est aussi appelée « constructor ». Elle est appelée par Python chaque fois que l’on instancie un objet.

Constructor crée l’état initial de l’objet avec l’ensemble minimal de paramètres dont il a besoin pour exister. Modifions la classe Cookie, afin qu’elle accepte des paramètres dans constructor.

class Cookie:
	# Constructor
	def __init__(self, name, shape, chips='Chocolate'):
		# Instance attributes
		self.name = name
		self.shape = shape
		self.chips = chips

Dans la classe Cookie, chaque cookie doit avoir name, shape et chips. Nous avons défini le dernier comme « Chocolate ».

D’autre part, self fait référence à l’instance de la classe (l’objet lui-même).

Essayez de coller la classe dans le shell et créez une instance du cookie comme d’habitude.

cookie2 = Cookie()
# TypeError

Vous obtiendrez une erreur. C’est parce que vous devez fournir l’ensemble minimal de données dont l’objet a besoin pour vivre – dans ce cas, name et shape puisque nous avons déjà défini chips pour « Chocolate ».

cookie2 = Cookie('Awesome cookie', 'Star')

Pour accéder aux attributs d’une instance, vous devez utiliser la notation point.

cookie2.name
# 'Awesome cookie'
cookie2.shape
# 'Star'
cookie2.chips
# 'Chocolate'

Pour l’instant, la classe Cookie n’a rien de bien juteux. Ajoutons un exemple de méthode bake() pour rendre les choses plus intéressantes.

class Cookie:
	# Constructor
	def __init__(self, name, shape, chips='Chocolate'):
		# Instance attributes
		self.name = name
		self.shape = shape
		self.chips = chips

	# The object is passing itself as a parameter
	def bake(self):
		print(f'This {self.name}, is being baked with the shape {self.shape} and chips of {self.chips}')
		print('Enjoy your cookie!')

Pour appeler une méthode, utilisez la notation point et invoquez-la comme une fonction.

cookie3 = Cookie('Baked cookie', 'Tree')
cookie3.bake()
# This Baked cookie, is being baked with the shape Tree and chips of Chocolate
Enjoy your cookie!

Les 4 piliers de la POO dans Python

La programmation orientée objet comprend quatre piliers principaux :

1. Abstraction

L’abstraction cache la fonctionnalité interne d’une application à l’utilisateur. L’utilisateur peut être soit le client final, soit d’autres développeurs.

Nous pouvons trouver l’abstraction dans notre vie quotidienne. Par exemple, vous savez comment utiliser votre téléphone, mais vous ne savez probablement pas exactement ce qui se passe à l’intérieur chaque fois que vous ouvrez une application.

Un autre exemple est Python lui-même. Vous savez comment l’utiliser pour créer des logiciels fonctionnels, et vous pouvez le faire même si vous ne comprenez pas les mécanismes internes de Python.

Appliquer la même chose au code permet de rassembler tous les objets d’un problème et d’abstraire les fonctionnalités standard en classes.

2. Héritage

L’héritage nous permet de définir de multiples sous-classes à partir d’une classe déjà définie.

L’objectif principal est de suivre le principe DRY (Don’t Repeat Yourself). Vous serez en mesure de réutiliser beaucoup de code en implémentant tous les composants de partage dans des super-classes.

Vous pouvez y voir le concept réel de l’héritage génétique. Les enfants (sous-classe) sont le résultat de l’héritage entre deux parents (super-classe). Ils héritent de toutes les caractéristiques physiques (attributs) et de certains comportements communs (méthodes).

3. Polymorphisme

Le polymorphisme nous permet de modifier légèrement les méthodes et les attributs des sous-classes préalablement définies dans la super-classe.

Le sens littéral est « plusieurs formes ». C’est parce que nous construisons des méthodes ayant le même nom mais des fonctionnalités différentes.

Pour revenir à l’idée précédente, les enfants sont également un parfait exemple de polymorphisme. Ils peuvent hériter d’un comportement défini get_hungry() mais d’une manière légèrement différente, par exemple en ayant faim toutes les 4 heures au lieu de toutes les 6 heures.

4. Encapsulation

L’encapsulation est le processus par lequel nous protégeons l’intégrité interne des données dans une classe.

Bien qu’il n’existe pas d’instruction private dans Python, vous pouvez appliquer l’encapsulation en utilisant le mangling dans Python. Il existe des méthodes spéciales appelées getters et setters qui nous permettent d’accéder à des attributs et méthodes uniques.

Imaginons une classe Human qui possède un attribut unique nommé _height. Vous ne pouvez modifier cet attribut qu’en respectant certaines contraintes (il est presque impossible d’être plus grand que 3 mètres).

Construire un calculateur de résolution de forme de surface

L’un des avantages de Python est qu’il nous permet de créer une grande variété de logiciels, depuis un programme CLI (interface de ligne de commande) jusqu’à une application web complexe.

Maintenant que vous avez appris les concepts fondamentaux de la POO, il est temps de les appliquer à un projet réel.

Note : Tout le code suivant sera disponible dans ce dépôt GitHub. Un outil de révision de code qui nous aide à gérer les versions du code avec Git.

Votre tâche consiste à créer un calculateur d’aire pour les formes suivantes :

  • Square
  • Rectangle
  • Triangle
  • Circle
  • Hexagon

Classe de base de la forme

Tout d’abord, créez un fichier calculator.py et ouvrez-le. Puisque nous avons déjà les objets avec lesquels travailler, il sera facile d’en faire abstraction dans une classe.

Vous pouvez analyser les caractéristiques communes et découvrir que toutes ces formes sont des formes en 2D. Par conséquent, la meilleure option est de créer une classe Shape avec une méthode get_area() dont chaque forme héritera.

Note : Toutes les méthodes doivent être des verbes. C’est parce que cette méthode s’appelle get_area() et non area().

class Shape:
	def __init__(self):
		pass

	def get_area(self):
		pass

Le code ci-dessus définit la classe ; cependant, il n’y a rien d’intéressant dedans pour le moment.

Implémentons la fonctionnalité standard de la plupart de ces formes.

class Shape:
	def __init__(self, side1, side2):
		self.side1 = side1
		self.side2 = side2

	def get_area(self):
		return self.side1 * self.side2

	def __str__(self):
		return f'The area of this {self.__class__.__name__} is: {self.get_area()}'

Décomposons ce que nous faisons avec ce code :

  • Dans la méthode __init__, nous demandons deux paramètres, side1 et side2. Ceux-ci resteront des attributs d’instance.
  • La fonction get_area() renvoie la surface de la forme. Dans ce cas, elle utilise la formule de l’aire d’un rectangle car elle sera plus facile à mettre en œuvre avec d’autres formes.
  • La méthode __str__() est une « méthode magique » tout comme __init__(). Elle vous permet de modifier la façon dont une instance va sortir.
  • L’attribut masqué self.__class__.__name__ fait référence au nom de la classe. Si vous travaillez avec une classe Triangle, cet attribut sera « Triangle ».

Classe Rectangle

Puisque nous avons implémenté la formule de l’aire du rectangle, nous pouvons créer une simple classe Rectangle qui ne fait rien d’autre qu’hériter de la classe Shape.

Pour appliquer l’héritage dans Python, vous devez créer une classe comme d’habitude et entourer la super-classe dont vous voulez hériter avec des parenthèses.

# Folded base class
class Shape: ...
 
class Rectangle(Shape): # Superclass in Parenthesis
	pass

Classe square

Nous pouvons adopter une excellente approche du polymorphisme avec la classe Square.

Rappelez-vous qu’un carré est simplement un rectangle dont les quatre côtés sont tous égaux. Cela signifie que nous pouvons utiliser la même formule pour obtenir l’aire.

Nous pouvons le faire en modifiant la méthode init, en n’acceptant qu’un côté comme paramètre, et en passant la valeur de ce côté au constructeur de la classe Rectangle.

# Folded classes
class Shape: ...
class Rectangle(Shape): ...
 
class Square(Rectangle):
	def __init__(self, side):
		super().__init__(side, side)

Comme vous pouvez le voir, la super fonction transmet le paramètre side deux fois à la super-classe. En d’autres termes, elle transmet side à la fois comme side1 et side2 au constructeur précédemment défini.

Classe Triangle

Un triangle est deux fois moins grand que le rectangle qui l’entoure.

Relation entre les triangles et les rectangles (Source de l'image : tuteurs Varsity).
Relation entre les triangles et les rectangles (Source de l’image : tuteurs Varsity).

Par conséquent, nous pouvons hériter de la classe Rectangle et modifier la méthode get_area pour qu’elle corresponde à la formule de l’aire du triangle, qui est la moitié de la base multipliée par la hauteur.

# Folded classes
class Shape: ...
class Rectangle(Shape): ...
class Square(Rectangle): ...
 
class Triangle(Rectangle):
	def __init__(self, base, height):
		super().__init__(base, height)
 
	def get_area(self):
		area = super().get_area()
		return area / 2

Un autre cas d’utilisation de la fonction super() consiste à appeler une méthode définie dans la super-classe et à stocker le résultat dans une variable. C’est ce qui se passe dans la méthode get_area().

Classe circle

Vous pouvez trouver l’aire d’un cercle avec la formule πr², où r est le rayon du cercle. Cela signifie que nous devons modifier la méthode get_area() pour mettre en œuvre cette formule.

Note : Nous pouvons importer la valeur approximative de π du module mathématique

# Folded classes
class Shape: ...
class Rectangle(Shape): ...
class Square(Rectangle): ...
class Triangle(Rectangle): …
 
# At the start of the file
from math import pi
 
class Circle(Shape):
	def __init__(self, radius):
		self.radius = radius
 
	def get_area(self):
		return pi * (self.radius ** 2)

Le code ci-dessus définit la classe Circle, qui utilise un constructeur et des méthodes get_area() différents.

Bien que Circle hérite de la classe Shape, vous pouvez redéfinir chaque méthode et l’attribuer à votre guise.

Classe Regular Hexagon

Nous avons seulement besoin de la longueur d’un côté d’un hexagone régulier pour calculer son aire. C’est similaire à la classe Square, où nous ne passons qu’un argument au constructeur.

Formule de l'aire de l'hexagone (Source d'image : BYJU'S)
Formule de l’aire de l’hexagone (Source d’image : BYJU’S)

Cependant, la formule est tout à fait différente, et elle implique l’utilisation d’une racine carrée. C’est pourquoi vous utiliserez la fonction sqrt() du module mathématique.

# Folded classes
class Shape: ...
class Rectangle(Shape): ...
class Square(Rectangle): ...
class Triangle(Rectangle): …
class Circle(Shape): …
 
# Import square root
from math import sqrt
 
class Hexagon(Rectangle):
	
	def get_area(self):
		return (3 * sqrt(3) * self.side1 ** 2) / 2

Tester nos classes

Vous pouvez passer en mode interactif lorsque vous exécutez un fichier Python à l’aide d’un débogueur. La façon la plus simple de le faire est d’utiliser la fonction intégrée breakpoint.

Note : Cette fonction n’est disponible que dans Python 3.7 ou plus récent.

from math import pi, sqrt
# Folded classes
class Shape: ...
class Rectangle(Shape): ...
class Square(Rectangle): ...
class Triangle(Rectangle): …
class Circle(Shape): …
class Hexagon(Rectangle): …
 
breakpoint()

Maintenant, exécutez le fichier Python et jouez avec les classes que vous avez créées.

$ python calculator.py
 
(Pdb) rec = Rectangle(1, 2)(Pdb) print(rec)
The area of this Rectangle is: 2
(Pdb) sqr = Square(4)
(Pdb) print(sqr)
The area of this Square is: 16
(Pdb) tri = Triangle(2, 3)
(Pdb) print(tri)
The area of this Triangle is: 3.0
(Pdb) cir = Circle(4)
(Pdb) print(cir)
The area of this Circle is: 50.26548245743669
(Pdb) hex = Hexagon(3)
(Pdb) print(hex)
The area of this Hexagon is: 23.382685902179844

Défi

Créez une classe avec une méthode run où l’utilisateur peut choisir une forme et calculer son aire.

Une fois que vous avez relevé le défi, vous pouvez envoyer une demande de modification au dépôt GitHub ou publier votre solution dans la section des commentaires.

Résumé

La programmation orientée objet est un paradigme dans lequel nous résolvons les problèmes en les considérant comme des objets. Si vous comprenez la POO de Python, vous pouvez aussi l’appliquer facilement dans des langages comme Java, PHP, Javascript et C#.

Dans cet article, vous avez appris ce qui suit :

  • Le concept d’orientation objet dans Python
  • Les avantages de la programmation orientée objet par rapport à la programmation structurée
  • Les bases de la programmation orientée objet dans Python
  • Le concept de classes et comment les utiliser dans Python
  • Le constructeur d’une classe dans Python
  • Les méthodes et attributs dans Python
  • Les quatre piliers de la POO
  • La mise en œuvre de l’abstraction, de l’héritage et du polymorphisme dans un projet

Maintenant, c’est à vous de jouer !

Si vous avez aimé ce guide, consultez notre article sur les tutoriels Python.

Faites-nous part de votre solution à ce défi dans les commentaires ci-dessous ! Et n’oubliez pas de consulter notre guide comparatif entre Python et PHP.

Daniel Diaz

Daniel is a self-taught Python Developer, Technical Writer, and long-life learner. He enjoys creating software from scratch and explaining this process through stunning articles. Follow him on Twitter: @DaniDiazTech