|
@@ -6,6 +6,25 @@ |
|
|
|
|
|
|
|
|
\center \huge Orienté objet et classes |
|
|
\center \huge Orienté objet et classes |
|
|
|
|
|
|
|
|
|
|
|
# Un petit détour |
|
|
|
|
|
|
|
|
|
|
|
Un nouveau built-in: `id()` |
|
|
|
|
|
|
|
|
|
|
|
L'adresse de l'objet pointé par la variable: |
|
|
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
|
>>> a = 42532 |
|
|
|
|
|
>>> id(a) |
|
|
|
|
|
94295009035968 |
|
|
|
|
|
>>> b = a |
|
|
|
|
|
>>> id(b) # même objet |
|
|
|
|
|
94295009035968 |
|
|
|
|
|
>>> c = 42532 # objet différent, même valeur |
|
|
|
|
|
>>> id(c) |
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
On en aura besoin tout à l'heure. |
|
|
|
|
|
|
|
|
# Paradigmes |
|
|
# Paradigmes |
|
|
|
|
|
|
|
|
Une façon d'envisager le code. |
|
|
Une façon d'envisager le code. |
|
@@ -20,24 +39,19 @@ Il y en a plein d'autres! (*fonctionnel* notamment, dont on parlera un jour) |
|
|
* des fonctions qui manipulent des types simples ou des structures |
|
|
* des fonctions qui manipulent des types simples ou des structures |
|
|
* les fonctions sont appelées les unes après les autres |
|
|
* les fonctions sont appelées les unes après les autres |
|
|
|
|
|
|
|
|
Aujourd'hui on va parler de *l'orienté objet*. |
|
|
|
|
|
|
|
|
Aujourd'hui on va parler de *l'orienté objet*, OOP en anglais (ou juste OO) |
|
|
|
|
|
|
|
|
# Un petit détour |
|
|
|
|
|
|
|
|
# Orienté objet - une mauvaise définition |
|
|
|
|
|
|
|
|
Un nouveau built-in: `id()` |
|
|
|
|
|
|
|
|
Un "objet" informatique *représente* un véritable "objet" physique |
|
|
|
|
|
dans le vrai monde véritable. |
|
|
|
|
|
|
|
|
L'adresse de l'objet pointé par la variable: |
|
|
|
|
|
|
|
|
Ce n'est pas une très bonne définition: |
|
|
|
|
|
|
|
|
``` |
|
|
|
|
|
>>> a = 42532 |
|
|
|
|
|
>>> id(a) |
|
|
|
|
|
94295009035968 |
|
|
|
|
|
>>> b = a |
|
|
|
|
|
>>> id(b) # même objet |
|
|
|
|
|
94295009035968 |
|
|
|
|
|
>>> c = 42532 # objet différent, même valeur |
|
|
|
|
|
>>> id(c) |
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
1. Ce n'est pas nécessaire |
|
|
|
|
|
2. Ce n'est même pas forcément souhaitable! |
|
|
|
|
|
|
|
|
|
|
|
Je le mentionne juste parce que c'est une idée reçue très répandue. |
|
|
|
|
|
|
|
|
# Orienté objet - 1ère définition |
|
|
# Orienté objet - 1ère définition |
|
|
|
|
|
|
|
@@ -48,7 +62,6 @@ Mettre au même endroit: |
|
|
|
|
|
|
|
|
L'important c'est que les deux aillent ensemble |
|
|
L'important c'est que les deux aillent ensemble |
|
|
|
|
|
|
|
|
OOP en Anglais (ou juste OO) |
|
|
|
|
|
|
|
|
|
|
|
# Orienté objet - 2ème définition |
|
|
# Orienté objet - 2ème définition |
|
|
|
|
|
|
|
@@ -59,6 +72,7 @@ Notamment, les cellules ne "voient" que leur état interne. |
|
|
On peut envoyer un message d'une cellule à une autre *sans* connaître |
|
|
On peut envoyer un message d'une cellule à une autre *sans* connaître |
|
|
beaucoup de détails à propos du destinataire du message |
|
|
beaucoup de détails à propos du destinataire du message |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Les classes |
|
|
# Les classes |
|
|
|
|
|
|
|
|
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. |
|
@@ -67,7 +81,9 @@ Mais notez bien qu'on peut faire de l'orienté objet *sans* classes! |
|
|
|
|
|
|
|
|
# Le plan de construction |
|
|
# Le plan de construction |
|
|
|
|
|
|
|
|
La seule chose dont on a besoin, c'est le mot-clé `class` et un nom. |
|
|
|
|
|
|
|
|
La seule chose dont on a besoin pour construire un objet, c'est un plan. |
|
|
|
|
|
|
|
|
|
|
|
On note le plan avec le mot-clé `class` et un nom: |
|
|
|
|
|
|
|
|
```python |
|
|
```python |
|
|
class MyObject: |
|
|
class MyObject: |
|
@@ -80,17 +96,29 @@ La classe est le plan de construction de notre objet. |
|
|
|
|
|
|
|
|
```python |
|
|
```python |
|
|
>>> object_1 = MyObject() |
|
|
>>> object_1 = MyObject() |
|
|
>>> object_2 = MyObject() |
|
|
|
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
Python ne sait rien de l'objet à part son adresse on mémoire et son nom: |
|
|
Python ne sait rien de l'objet à part son adresse on mémoire et son nom: |
|
|
|
|
|
|
|
|
```python |
|
|
```python |
|
|
print(object_1) |
|
|
|
|
|
|
|
|
>>> id(object_1) |
|
|
|
|
|
139993522758320 |
|
|
|
|
|
>>> print(object_1) |
|
|
<__main__.MyObject at 0x7f52c831e2b0> |
|
|
<__main__.MyObject at 0x7f52c831e2b0> |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
On appelle `object_1` et `object_2` des *instances* de la classe `MyObject`. |
|
|
|
|
|
|
|
|
On appelle `object_1` une *instance* de la classe `MyObject`. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Créons d'autres objets |
|
|
|
|
|
|
|
|
|
|
|
```python |
|
|
|
|
|
>>> object_2 = MyObject() |
|
|
|
|
|
>>> print(object_2) |
|
|
|
|
|
<__main__.MyObject at 0x7fb39e5ac748> |
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
Une autre adresse mémoire, donc un objet différent. |
|
|
|
|
|
|
|
|
# Méthodes |
|
|
# Méthodes |
|
|
|
|
|
|
|
@@ -106,7 +134,7 @@ C'est tout! |
|
|
|
|
|
|
|
|
# Méthodes - 2 |
|
|
# Méthodes - 2 |
|
|
|
|
|
|
|
|
La méthode n'existe pas en dehors de la classe (souvenez vous des cellules !) |
|
|
|
|
|
|
|
|
La méthode n'existe pas en dehors de la classe - souvenez vous des cellules ! |
|
|
|
|
|
|
|
|
``` |
|
|
``` |
|
|
>>> my_method() |
|
|
>>> my_method() |
|
@@ -116,8 +144,14 @@ NameError |
|
|
Hello, <MyObject at 0x7f52c9f6d6d8> |
|
|
Hello, <MyObject at 0x7f52c9f6d6d8> |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
Notez que `my_method` a pris en premier argument ce qu'il y avait *à gauche* du point: |
|
|
|
|
|
|
|
|
# Méthodes - 2 |
|
|
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
|
>>> object.my_method() |
|
|
|
|
|
Hello, <MyObject at 0x7f52c9f6d6d8> |
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
Notez que `my_method` a pris en premier argument ce qu'il y avait *à gauche* du point. |
|
|
D'ailleurs, ce code fonctionne aussi et retourne *la même chose*: |
|
|
D'ailleurs, ce code fonctionne aussi et retourne *la même chose*: |
|
|
|
|
|
|
|
|
``` |
|
|
``` |
|
@@ -138,7 +172,8 @@ class MyObject: |
|
|
```python |
|
|
```python |
|
|
>>> o = MyObject() |
|
|
>>> o = MyObject() |
|
|
>>> o.broken() |
|
|
>>> o.broken() |
|
|
TypeError: broken() takes 0 positional arguments but 1 was given |
|
|
|
|
|
|
|
|
TypeError: broken() takes 0 positional arguments |
|
|
|
|
|
but 1 was given |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
# Conventions |
|
|
# Conventions |
|
@@ -202,7 +237,7 @@ Avec `__init__`: |
|
|
|
|
|
|
|
|
* méthode "spéciale" |
|
|
* méthode "spéciale" |
|
|
* appelée automatiquement |
|
|
* appelée automatiquement |
|
|
* notez les deux underscores avant et après ('dunder' en Anglais) |
|
|
|
|
|
|
|
|
* notez les deux underscores avant et après ('dunder' en anglais) |
|
|
|
|
|
|
|
|
```python |
|
|
```python |
|
|
class MyObject: |
|
|
class MyObject: |
|
@@ -266,10 +301,6 @@ Un fichier `foo.py` correspond au module `foo` |
|
|
C'est pas tout à fait réciproque. Le module `foo` peut venir d'autre chose |
|
|
C'est pas tout à fait réciproque. Le module `foo` peut venir d'autre chose |
|
|
qu'un fichier. |
|
|
qu'un fichier. |
|
|
|
|
|
|
|
|
\vfill |
|
|
|
|
|
|
|
|
|
|
|
On y reviendra. |
|
|
|
|
|
|
|
|
|
|
|
# Importer un module |
|
|
# Importer un module |
|
|
|
|
|
|
|
|
Ou: accéder à du code provenant d'un *autre* fichier source. |
|
|
Ou: accéder à du code provenant d'un *autre* fichier source. |
|
@@ -353,7 +384,8 @@ Parfois, les gens conseillent d'utiliser `reload()` mais cette fonction n'est pa |
|
|
|
|
|
|
|
|
* Utile dans le REPL |
|
|
* Utile dans le REPL |
|
|
* Pas une très bonne idée dans du vrai code |
|
|
* Pas une très bonne idée dans du vrai code |
|
|
* On perd la trace de où vient la variable * Possibilité de collisions de noms |
|
|
|
|
|
|
|
|
* On perd la trace de où vient la variable |
|
|
|
|
|
* Possibilité de collisions de noms |
|
|
|
|
|
|
|
|
# Retour sur les scripts |
|
|
# Retour sur les scripts |
|
|
|
|
|
|
|
@@ -398,7 +430,7 @@ if __name__ == "__main__": |
|
|
Le `if` n'est vrai *que* quand on lance `python3 foo.py`, mais pas quand on appelle `import foo` depuis |
|
|
Le `if` n'est vrai *que* quand on lance `python3 foo.py`, mais pas quand on appelle `import foo` depuis |
|
|
un autre module. |
|
|
un autre module. |
|
|
|
|
|
|
|
|
La variable magique `__name__` est égale au nom du module quand il est importé, et à `__main__` sinon. |
|
|
|
|
|
|
|
|
La variable magique `__name__` est égale au nom du module quand il est importé, et à la string `"__main__"` sinon. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# La librarie standard (1) |
|
|
# La librarie standard (1) |
|
|