💡 Python & la POO#

Orienté objet

Les langage de programmation orientĂ© objet implĂ©mentent le paradigme de programmation orientĂ©e objet (POO). Ce paradigme consiste en la rĂ©union des donnĂ©es et des traitements associĂ©es Ă  ces donnĂ©es au sein d’entitĂ©s cohĂ©rentes appelĂ©es objets.

Indication

Une introduction plus gĂ©nĂ©rale sur la programmation orientĂ©e object est disponible ici : đŸ§© OOP

Langages Ă  classes ou Ă  prototypes#

LĂ  oĂč les choses se compliquent, c’est que tous les langages objets ne permettent pas de crĂ©er et manipuler des classes.

En effet, il existe deux types de langages objet :

  1. Les langages objets Ă  classes

  2. Les langages objets Ă  prototypes

Les langages objets Ă  prototypes (comme par exemple Javascript) ne permettent pas nativement de crĂ©er des classes, mĂȘme s’il manipulent des objets. Les objets y sont créés suivant un prototype (un autre objet) plutĂŽt que par instanciation d’une classe.

Python est un langage orienté objet qui a deux caractéristiques importantes :

  1. Il s’agit d’un langage Ă  classes, son approche orientĂ©e objet est dite « traditionnelle », elle s’apparente de celle de C++, en diffĂ©renciant les concepts de classe et d’objet.

  2. Le dĂ©veloppeur n’est pas obligĂ© d’employer une approche objet quand il Ă©crit du code Python.

Important

Python est « multi-paradigme », c’est Ă  dire qu’il autorise plusieurs façon de dĂ©velopper et de concevoir ses programmes. L’une d’entre elle est la programmation orientĂ©e object, bien que Python n’impose pas de coder en OOP son fonctionnement interne est fortement teintĂ© d’objet.

Tout est un object#

En python, tout est un object, il suffit d’exĂ©cuter ce script pour s’en rendre compte:

print(type(42))
print(type("HelloWorld"))
print(type([]))
print(type(()))
print(type({}))

def func(var):
   print(var)

print(type(func))

et nous obtiendrons cette sortie:

<class 'int'>
<class 'str'>
<class 'list'>
<class 'tuple'>
<class 'dict'>
<class 'function'>

Ces Ă©lĂ©ments sont tous de types diffĂ©rent mais ont un point en commun le terme class. A l’instar de l’instruction def qui dĂ©finit une fonction, class dĂ©finit une classe d’object python.

Définir ses propres objets#

Nous allons traduire la classe définit au format UML

https://www.plantuml.com/plantuml/svg/JOwn2W9134JxV4LAHR0GRAok4B7o5oItkzujjvj8aiL2_7SN577AcJVC3EQatch1c5cCcbvhybcYWGKg2NVRFTYI-KvA5KSAowJIE0OfekXAR3rAx7zKJ3TgnK_2Vg6QyDnR0A6G6Hw_C_W4xDfm1mvehfad-5YFMQZcrVfdlm26nB6_V0C=

Diagramme UML de notre classe dinosaure#

Notre premiĂšre classe en python#
class Dinosaur(object):

   def __init__(self, name: str):
      self.name = name

   def whoami(self) -> str:
      return f"I'm {self.name}"

Quelques remarques:

  • le mot clĂ© class dĂ©finit notre classe d’object, par convention son nom commence par une majuscule.

  • notre classe dĂ©finit deux mĂ©thodes.

  • __init__ est l’initialisateur de notre classe et permet de dĂ©finir les attributs de notre instance.

Important

Toute mĂ©thode d’instance doit prendre en premier paramĂštre la rĂ©fĂ©rence vers l’instance via le mot clĂ© self

Classe et instance#

Une classe est un « blueprint » qui nous permet de crĂ©er des objet, elle dĂ©finit ses attributs et mĂ©thodes. Pour crĂ©er une instance il faut l’instancier:

rexy = Dinosaur('Rexy')
clever_girl = Dinosaur('Clever Girl')

print(type(rexy))
print(type(clever_girl))

Nous avons crĂ©er deux instances de notre classe Dinosaur, celles-ci sont autonomes, il s’agit de deux object bien distincts.

Attributs#

Un attribut est une donnĂ©e associĂ© Ă  un object, celui-ci peut contenir n’importe quel object python.

Accéder aux attributs#
print(rexy.name)
print(clever_girl.name)
Modifier un attribut#
clever_girl.name = 'The Big One'

print(clever_girl.name)
Ajouter un attribut#
clever_girl.specie = 'Velociraptor'

print(clever_girl.specie)

Important

Tous les attributs et méthodes des classes Python sont « publics » au sens de C++.

We are all consenting adults

—Guido van Rossum, (CrĂ©ateur de Python).

La convention de prĂ©fixer un attribut et/ou une mĂ©thode par _ indique qu’il s’agit d’un attribut interne et d’éviter de l’utiliser.

Méthodes#

Une mĂ©hode est une « fonction associĂ© Ă  un object », elle peut utiliser ses attributs, les modifier et faire appels Ă  d’autres mĂ©thodes de l’object.

Attention

Toutes les mĂ©thodes prennent une variable self (sauf les mĂ©thodes de classe) comme premier argument. Cette variable est une rĂ©fĂ©rence Ă  l’objet manipulĂ©.

Appel à une méthode#
print(rexy.whoami())

Indication

On ne spĂ©cifie pas le paramĂštre self lorsque l’on manipule une instance. Le lien entre l’instance et la mĂ©thode est dĂ©jĂ  fait.

La méthode __init__#

La mĂ©thode __init__ est comme son nom l’indique un initialisateur, l’instance de notre classe est dĂ©jĂ  crĂ©er Ă  ce moment lĂ .

En Python, on n’est pas tenu de dĂ©clarer tous les attributs de la classe comme dans d’autres langages : on peut se contenter de les initialiser au sein de la mĂ©thode __init__ !

Héritage#

Python supporte l’hĂ©ritage simple et l’hĂ©ritage multiple. La crĂ©ation d’une classe fille est relativement simple, il suffit de prĂ©ciser entre parenthĂšses le nom de la classe mĂšre lors de la dĂ©claration de sa fille.

class Sauropod(Dinosaur):

    def __init__(self, name):
        super(Sauropod, self).__init__(**kwargs)
        self.family = "Sauropod"

Note

Un Ă©lĂ©ment important Ă  remarquer est l’utilisation de la fonction super(), elle permet, de maniĂšre « intelligente », de dĂ©lĂ©guer Ă  la ou les classe(s) mĂšre(s) l’exĂ©cution de certains traitements.

On l’utilise donc notamment pour appeler, depuis une classe fille, le constructeur de la classe mùre.

La mĂ©thode super() utilise l’algorithme du MRO (Method Resolution Order) pour parcourir l’arbre des hĂ©ritages.