Programmation orienté objet: introduction
Directory
serie
- partie 1: Introduction $ \Leftarrow $
- partie 2: En pratique
- partie 3: Attributs
- partie 4: Héritage
- partie 5: Héritage multiple et composition
- partie 6: Méthodes magiques
Sources
Recapitulatif
- Un objet se crée en instanciant une classe
- Une classe est un plan décrivant un objet et est composé de
- méthodes (comportement)
- attributs (données)
class Article:
def __init__(self, titre):
self.titre = titre
a1 = Article("J'aime la viande")
print(a1.titre)
-
Les méthodes nommées
__methode__
(avec deux underscores) sont appelées automatiquement dans certaines conditions.__init__
est appelée automatiquement après la création de l’objet, et on s’en sert pour créer l’état de départ de l’objet (initialiser). -
self
est le premier paramètre qu’on passe à une méthode et représente l’objet en cours.
Base
La programmation orienté objet est un style (paradigme) de programmation qui permet de regrouper au même endroit le comportement (fonctions) et les données (structures) qui sont faites pour aller ensemble.
La POO a pour principal attrait de permettre de proposer une belle API, c’est à dire de créer du code réutilisable et facile à manipuler.
Il n’y a rien qu’on puisse faire en POO qu’on ne puisse faire autrement. On l’utilise principalement pour donner un style au code.
En réalité, on fait de la POO principalement pour faciliter la vie de ceux qui vont utiliser notre code plus tard.
Objet
Un objet est un moyen de dire à la machine : “Ce random nom
possède telle donnée, et fait telle chose avec”.
En Python absolument tout est un objet.
Créer des objets se fait en deux étapes:
- Décrire à quoi ressemble l’objet $ \Rightarrow $ classe
class DescriptionObjet:
pass
- Création de l’objet
>>> nouvel_objet = DescriptionObjet()
>>> print(nouvel_objet)
<__main__.DescriptionObjet object at 0x7f3d96b8a898>
La variable nouvel_objet
contient un objet issu de la classe DescriptionObjet
.
La variable nouvel_objet
contient une instance de DescriptionObjet
$ \Rightarrow $ L’action de créer un objet à partir d’une classe est appelée instanciation.
Python ne connait pour le moment que le nom et l’adresse en mémoire de l’objet et c’est ce qu’il affiche suite à un print()
.
On peut créer autant d’objets que l’on veut à partir d’une classe.
Méthodes
Fonctions déclarées à l’intérieur d’une classe.
class DescriptionObjet:
def methode(objet_en_cours):
print("poule")
Cette fonction méthode n’existe pas en dehors de la classe.
>>> methode()
File "/home/sol/Code/Python/Tuto/Class/04SamEtMax/00.py", line 5, in <module>
methode()
NameError: name 'methode' is not defined
Mais elle est attachée à chaque objet. On peut l’utiliser via la notation par point. Il nous faut donc automatiquement l’instance d’une classe pour appeler une méthode:
>>> nouvel_objet = DescriptionObjet()
>>> nouvel_objet.methode()
poule
Objet en cours (self)
Quand on appel une méthode depuis un objet, l’objet est passé en premier paramètre par Python. C’est automatique et invisible.
class DescriptionObjet:
def methode(objet_en_cours):
return objet_en_cours
nouvel_objet = DescriptionObjet()
print(nouvel_objet)
print(nouvel_objet.methode())
output:
<__main__.DescriptionObjet object at 0x7f48f271e940>
<__main__.DescriptionObjet object at 0x7f48f271e940>
nouvel_objet
et objet_en_cours
contiennent la même chose : l’objet en cours.
objet_en_cours
est le nom que nous avons donné à notre premier argument, mais Python passe toujours automatiquement en premier argument l’objet en cours afin que nous puissions modifier cet objet à l’intérieur d’une méthode.
Paramètre objet_en_cours
$ \Rightarrow $ instance courante
Une méthode doit toujours déclarer au moins un paramètre pour accueillir la référence à l’objet en cours !
Conventions
- On nomme les classes en CamelCase
- On nomme le reste en minuscules avec des underscores:
nom_de_methode
nom_d_attribut
- Le premier paramètre (
objet_en_cours
) se nomeself
- Les méthodes appelées automatiquement sont appelées
__nom_de_methode__
(avec deux underscores)
Attributs
Tout comme les méthodes sont des fonctions attachées à un objet, les attributs sont des variables attachées à un objet.
En réalité les méthodes sont aussi des attributs
Python est un langage dynamique et permet d’ajouter n’importe quel attribut à n’importe quel objet via la notation par point:
>>> nouvel_objet.attribut
Traceback (most recent call last):
File "/home/sol/Code/Python/Tuto/Class/04SamEtMax/00.py", line 9, in <module>
print(nouvel_objet.attribut)
AttributeError: 'DescriptionObjet' object has no attribute 'attribut'
>>> nouvel_objet.nouvel_attribut = "poule"
>>> print(nouvel_objet.nouvel_attribut)
poule
Intéret de self
:
class DescriptionObjet:
def afficher(self):
print(self.attribut)
def modifier(self):
self.attribut = "autre valeur"
On peut accéder aux attributs depuis l’intérieur et l’extérieur d’un objet:
>>> un_objet = DescriptionObjet()
>>> un_objet.afficher()
Comme l’attribut n’existe pas encore Python renvoie:
Traceback (most recent call last):
File "/home/sol/Code/Python/Tuto/Class/04SamEtMax/00.py", line 9, in <module>
un_objet.afficher()
File "/home/sol/Code/Python/Tuto/Class/04SamEtMax/00.py", line 3, in afficher
print(self.attribut)
AttributeError: 'DescriptionObjet' object has no attribute 'attribut'
>>> un_objet.attribut = "maintenant il existe !"
>>> un_objet.afficher()
maintenant il existe !
>>> un_objet.modifier()
>>> un_objet.attribut
'autre valeur'
Une méthode peut modifier l’objet en cours en fonction des paramètres passés:
class DescriptionObjet:
def afficher(self):
print("valeur actuelle:", self.attribut)
def modifier(self, valeur):
self.attribut = valeur * 2
>>> un_objet = DescriptionObjet()
>>> un_objet.attribut = 1
>>> un_objet.afficher()
valeur actuelle: 1
>>> un_objet.modifier(2)
>>> un_objet.afficher()
valeur actuelle: 4
Les méthodes servent à retourner les valeurs à l’intérieur de l’objet, ou à les modifier.
Initialisation d’un objet
On utilise une méthode appelée automatiquement (__methode__
) après la création de l’objet pour initialiser des attributs sans devoir les créer à chaque fois. Cette méthode est __init__
.
class DescriptionObjet:
def __init__(self):
print("L'objet a ete cree !")
print("Cette methode est appelee automatiquement")
un_objet = DescriptionObjet()
output:
L'objet a ete cree !
Cette methode est appelee automatiquement
__init__
est une méthode tout à fait ordinaire. Seul le nom est important car il est detecté par Python qui l’appelle au bon moment.
C’est principalement utile pour fournir un état de départ:
class Voiture:
def __init__(self):
self.carburent = 100
self.couleur = "noire"
v = Voiture()
print(v.couleur)
print(v.carburent)
output:
noire
100
Si on passe des paramètres à l’instanciation, ils sont passés automatiquement à __init__
qui comme toutes les fonctions méthodes peut avoir des paramètres par défaut.
class Voiture:
def __init__(self, cb_de_carburent=100, quelle_couleur="noire"):
self.carburent = cb_de_carburent
self.couleur = quelle_couleur
v1 = Voiture()
print("\nv1:")
print(v1.couleur)
print(v1.carburent)
v2 = Voiture(50, 'rouge')
print("\nv2:")
print(v2.couleur)
print(v2.carburent)
v3 = Voiture(quelle_couleur="gris")
print("\nv3:")
print(v3.couleur)
print(v3.carburent)
v4 = Voiture(12)
print("\nv4:")
print(v4.couleur)
print(v4.carburent)
output:
v1:
noire
100
v2:
rouge
50
v3:
gris
100
v4:
noire
12
Par convention les noms de paramètres sont les mêmes que ceux des attributs:
class Voiture:
def __init__(self, carburent=100, couleur="noire"):
self.carburent = carburent
self.couleur = couleur
Self
Pour mieux comprendre self
nous allons utiliser la fonction id()
qui retourne l’adresse en mémoire de l’objet passé en argument.
id()
retourne un int,hex()
nous permet de l’avoir sous format hexadecimal
La méthode print_self()
de la classe suivante nous permet d’identidier self
:
class Article:
def __init__(self, titre):
self.titre = titre
def print_self(self):
print(self.titre)
print(self)
print(hex(id(self)))
article = Article("Poules et cochons")
Affichage du titre et des adresses de l’article
:
>>> print(article.titre)
Poules et cochons
>>> print(article)
<__main__.Article object at 0x7f502be38c88>
>>> print(hex(id(article)))
0x7f502be38c88
Utilisation de la méthode self_print()
:
>>> articl1.print_self()
Poules et cochons
<__main__.Article object at 0x7f502be38c88>
0x7f502be38c88
Nous constatons que c’est exactement la même chose. self
est article
. C’est ça que veut dire être l’objet en cours.