* Des structures de données (listes, dictionnaires, ...)
* Des structures de données (listes, dictionnaires, ...)
* Des fonctions qui manipulent ces types ou ces types
* Des fonctions qui manipulent ces données ou ces types
* Des fonctions qui s’appellent les unes les autres
* Des fonctions qui s’appellent les unes les autres
On appelle cet ensemble de concepts, cette façon d'écrire du code, un *paradigme* -
On appelle cet ensemble de concepts, cette façon d'écrire du code, un *paradigme* -
@@ -109,9 +109,9 @@ L'important c'est que les deux aillent ensemble!
pour le moment ...*
pour le moment ...*
# Les classes
# Classes et instances
On va parler *d'une* façon de faire de l'orienté objet: avec des classes.
On va parler *d'une* façon de faire de l'orienté objet: avec des classes et des instances.
Mais notez bien qu'on peut faire de l'orienté objet *sans* classes!
Mais notez bien qu'on peut faire de l'orienté objet *sans* classes!
@@ -122,42 +122,42 @@ Pour construire un objet en Python, on a besoin d'un *plan de construction*.
On appelle ce plan une *classe* et on la définit ainsi:
On appelle ce plan une *classe* et on la définit ainsi:
```python
```python
class MonObjet:
class MaClasse:
# du code ici
# du code ici
```
```
Comme les fonctions, les classes contiennent un *corps*, qui est le bloc *identé* en dessous
Comme les fonctions, les classes contiennent un *corps*, qui est le bloc *identé* en dessous
du mot-clé `class`, de nom de la classe et du `:` en fin de ligne
du mot-clé `class`, de nom de la classe et du `:` en fin de ligne
# Créons des objets
# Créons des instances
On peut faire un plan de construction vide avec le mot clé pass:
On peut faire un plan de construction vide avec le mot clé pass:
```python
```python
class MonObjet:
class MaClasse:
pass
pass
```
```
Dans ce cas, on crée un objet en mettant le nom de la classe suivi d'une paire de parenthèses -
Dans ce cas, on crée une instance en écrivant le nom de la classe suivi d'une paire de parenthèses -
un peu comme pour appeler une fonction:
un peu comme pour appeler une fonction:
```python
```python
>>> objet_1 = MonObjet()
>>> mon_instance = MaClasse()
```
```
Ici, `objet_1` est une *instance* de la classe `MonObjet`.
Ici, `mon_instance` est une *instance* de la classe `MaClasse`.
# Attributs
# Attributs
Les attributs sont des éléments **nommés** à *l'intérieur* d'un objet.
Les attributs sont des éléments **nommés** à *l'intérieur* d'une instance.
On peut y accéder avec la syntaxe `<objet>.<attribut>`:
On peut y accéder avec la syntaxe `<instance>.<attribut>`:
```python
```python
y = a.x
y = a.x
```
```
Ici, `y` est l'attribut `x` de l'objet `a`.
Ici, `y` est une variable qui a la valeur de l'attribut `x` de l'instance `a`.
# Attributs - 2
# Attributs - 2
@@ -168,7 +168,7 @@ func = a.x
func(10)
func(10)
```
```
Ici, on crée une variable `func` qui prend la valeur de l'attribut `x` dans l'objet `a`, puis
Ici, on crée une variable `func` qui prend la valeur de l'attribut `x` dans l'instance `a`, puis
on l'appelle avec l'argument `10` à la ligne suivante.
on l'appelle avec l'argument `10` à la ligne suivante.
Le code suivant fait exactement la même chose, mais avec une ligne de moins:
Le code suivant fait exactement la même chose, mais avec une ligne de moins:
@@ -194,10 +194,10 @@ On reviendra sur les modules dans un prochain chapitre.
# Attributs - 4
# Attributs - 4
On peut *créer* des attributs dans *n'importe quel objet*, en utilisant l'*assignation*:
On peut *créer* des attributs dans *n'importe quel instance*, en utilisant l'*assignation*:
```python
```python
>>> mon_instance = MonObjet()
>>> mon_instance = MaClasse()
# Création de l'attribut `x` dans `mon_instance`
# Création de l'attribut `x` dans `mon_instance`
>>> mon_instance.x = 42
>>> mon_instance.x = 42
@@ -215,29 +215,28 @@ On utilise `def`, comme pour les fonctions, mais les méthodes *doivent* avoir a
moins un argument appelé `self`, et être à l'intérieur du bloc de la classe:
moins un argument appelé `self`, et être à l'intérieur du bloc de la classe:
```python
```python
class MonObjet:
class MaClasse:
def ma_méthode(self):
def ma_méthode(self):
return 42
return 42
```
```
# Méthodes - appel
# Méthodes - appel
Une méthode ne peut être appelée que depuis une *instance* de
l'objet:
Une méthode ne peut être appelée que depuis une *instance*:
```python
```python
class MonObjet:
class MaClasse:
def ma_méthode(self):
def ma_méthode(self):
return 42
return 42
>>> ma_méthode()
>>> ma_méthode()
Erreur
Erreur
>>> mon_instance = MonObjet()
>>> mon_instance = MaClasse()
>>> mon_instance.ma_méthode()
>>> mon_instance.ma_méthode()
42
42
```
```
Notez qu'on ne passe *pas* d'argument quand on appelle `ma_méthode` depuis l'instance de l'objet.
Notez qu'on ne passe *pas* d'argument quand on appelle `ma_méthode` depuis l'instance de la classe.
# Méthodes et attributs - 1
# Méthodes et attributs - 1
@@ -247,13 +246,13 @@ Notez qu'on ne passe *pas* d'argument quand on appelle `ma_méthode` depuis l'in
On peut le voir en utilisant des attributs:
On peut le voir en utilisant des attributs:
```python
```python
class MonObjet:
class MaClasse:
def affiche_attribut_x(self):
def affiche_attribut_x(self):
# Accès à l'attribut `x` dans `self`
# Accès à l'attribut `x` dans `self`
print(self.x)
print(self.x)
>>> mon_instance = MonObjet()
>>> mon_instance = MaClasse()
>>> mon_instance.x = 42
>>> mon_instance.x = 42
>>> mon_instance.affiche_attribut_x()
>>> mon_instance.affiche_attribut_x()
42
42
@@ -264,13 +263,13 @@ class MonObjet:
On peut aussi *créer* des attributs dans une méthode:
On peut aussi *créer* des attributs dans une méthode:
```python
```python
class MonObjet:
class MaClasse:
def crée_attribut_x(self):
def crée_attribut_x(self):
self.x = 42
self.x = 42
def affiche_attribut_x(self):
def affiche_attribut_x(self):
print(self.x)
print(self.x)
>>> mon_instance = MonObjet()
>>> mon_instance = MaClasse()
>>> mon_instance.affiche_attribut_x()
>>> mon_instance.affiche_attribut_x()
# Erreur: `mon_instance` n'a pas d'attribut `x`
# Erreur: `mon_instance` n'a pas d'attribut `x`
@@ -288,14 +287,14 @@ Par exemple, pour créer un attribut avec une certaine valeur:
```python
```python
class MonObjet
class MaClasse
def crée_attribut_x(self, valeur_de_x):
def crée_attribut_x(self, valeur_de_x):
self.x = valeur_de_x
self.x = valeur_de_x
def affiche_attribut_x(self);
def affiche_attribut_x(self);
print(self.x)
print(self.x)
>>> mon_instance = MonObjet()
>>> mon_instance = MaClasse()
>>> mon_instance.crée_attribut_x(42)
>>> mon_instance.crée_attribut_x(42)
>>> mon_instance.affiche_attribut_x()
>>> mon_instance.affiche_attribut_x()
42
42
@@ -303,11 +302,11 @@ class MonObjet
# Méthodes appelant d'autres méthodes - 1
# Méthodes appelant d'autres méthodes - 1
Comme les méthodes sont *aussi* des attributs, les méthodes d'un objet peuvent s'appeler
Comme les méthodes sont *aussi* des attributs, les méthodes d'une classe peuvent s'appeler
les unes les autres:
les unes les autres:
```python
```python
class MonObjet:
class MaClasse:
def méthode_1(self):
def méthode_1(self):
print("démarrage de la méthode 1")
print("démarrage de la méthode 1")
print("la méthode 1 affiche bonjour")
print("la méthode 1 affiche bonjour")
@@ -324,7 +323,7 @@ class MonObjet:
# Méthodes appelant d'autres méthodes - 2
# Méthodes appelant d'autres méthodes - 2
```python
```python
>>> mon_instance = MonObjet()
>>> mon_instance = MaClasse()
>>> mon_instance.méthode_2()
>>> mon_instance.méthode_2()
```
```
@@ -340,7 +339,7 @@ fin de la méthode 2
# Une méthode spéciale
# Une méthode spéciale
Si vous définissez une méthode `__init__`, celle-ci est appelée *automatiquement*
Si vous définissez une méthode `__init__`, celle-ci est appelée *automatiquement*
quand l'objet est construit.
quand l'instance est construite.
On dit que c'est une méthode "magique" parce qu'elle fait quelque chose _sans_ qu'on
On dit que c'est une méthode "magique" parce qu'elle fait quelque chose _sans_ qu'on
l'appelle explicitement.
l'appelle explicitement.
@@ -351,12 +350,12 @@ On utilise souvent `__init__` pour créer des attributs
```python
```python
class MonObjet:
class MaClasse:
def __init__(self):
def __init__(self):
self.x = 1
self.x = 1
self.y = 2
self.y = 2
>>> mon_instance = MonObjet()
>>> mon_instance = MaClasse()
# __init__ est appelée automatiquement!
# __init__ est appelée automatiquement!
>>> mon_instance.x
>>> mon_instance.x
@@ -370,7 +369,7 @@ class MonObjet:
On prend souvent les *valeurs* des attributs à créer en arguments de la méthode `__init__ `.
On prend souvent les *valeurs* des attributs à créer en arguments de la méthode `__init__ `.
```python
```python
class MonObjet:
class MaClasse:
def __init__(self, x, y):
def __init__(self, x, y):
self.x = x
self.x = x
self.y = y
self.y = y
@@ -380,21 +379,26 @@ Dans ce cas, les arguments de la méthode `__init__` apparaissent à l'intérieu
nom de la classe:
nom de la classe:
```
```
>>> mon_instance = MonObjet(3, 4)
>>> mon_instance = MaClasse(3, 4)
>>> mon_instance.x
>>> mon_instance.x
3
3
>>> mon_instance.y
>>> mon_instance.y
4
4
```
```
*Pour cette raison, `__init__` est souvent appelé le _constructeur_ de la classe.*
D'où le nom: `__init__` sert a initialiser les attributs de la classe.
# Constructeurs
Note: on appelle parfois la méthode `__init__` un constructeur, un terme qui est employé pour d'autres langages qui utilisent également des classes, comme Java ou C++.
Mais c'est un abus de langage: `__init__` en Python ne construit rien!
# Récapitulatif
# Récapitulatif
* Classe: plan de construction
* Classe: plan de construction
* Objet: ce qu'on crée avec le plan
* Attribut: variable dans un objet
* Instance: objet issue d'une classe
* Instance: ce qu'on construit avec une classe
* Attribut: variable dans une instance
* Méthode: fonction dans une classe (qui prend `self` en premier argument)
* Méthode: fonction dans une classe (qui prend `self` en premier argument)
* `__init__`: méthode magique appelée automatiquement pendant l'instanciation
* `__init__`: méthode magique appelée automatiquement pendant l'instanciation
@@ -421,7 +425,7 @@ Ou encore *d'interface* et de *d'implémentation*.