|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- % Programmation avec Python (Épisode 7)
- % Dimitri Merejkowsky
-
-
- \center \huge Rappels
-
-
- # Classes vides
-
- Définition:
- ```python
- class MaClasse:
- pass
- ```
-
- Instanciation:
- ```python
- >>> instance_1 = MaClasse()
- ```
-
- # Attributs
-
- Un attribut est une variable _à l'intérieur_ d'autre chose (par exemple une instance de classe).
-
- ```python
- >>> mon_instance = MaClasse()
- # création de l'attribut `x` dans mon_instance:
- >>> mon_instance.x = 42
- # accès à l'attribut `x` dans mon_instance:
- >>> mon_instance.x
- 42
- ```
-
- # Méthodes
-
- Une méthode est une fonction définie à l'intérieur d'une classe:
-
- Définition:
- ```python
- class MaClasse:
- def ma_méthode(self):
- return 42
- ```
-
- Les méthodes sont des attributs des instances de classes:
-
- ```python
- class MaClasse:
- def ma_méthode(self):
- return 42
- >>> ma_méthode()
- Erreur
- >>> mon_instance = MaClasse()
- >>> mon_instance.ma_méthode()
- 42
- ```
-
-
- # self
-
- `self` *prend la valeur de l'instance courante* quand la méthode est appelée.
-
- ```python
- class MaClasse:
- def affiche_attribut_x(self):
- print(self.x)
-
- >>> mon_instance = MaClasse()
- >>> mon_instance.x = 42
- >>> mon_instance.affiche_attribut_x()
- 42
- ```
-
- # self (2)
-
- On peut aussi *créer* des attributs dans une méthode:
-
- ```python
- class MaClasse:
- def crée_attribut_x(self):
- self.x = 42
- def affiche_attribut_x(self):
- print(self.x)
-
- >>> mon_instance = MaClasse()
- >>> mon_instance.affiche_attribut_x()
- # Erreur: `mon_instance` n'a pas d'attribut `x`
-
- >>> mon_instance.crée_attribut_x()
- >>> mon_instance.affiche_attribut_x()
- 42
- ```
-
- # Méthodes avec arguments
-
- ```python
- class MaClasse
- def crée_attribut_x(self, valeur_de_x):
- self.x = valeur_de_x
-
- def affiche_attribut_x(self);
- print(self.x)
-
- >>> mon_instance = MaClasse()
- >>> mon_instance.crée_attribut_x(42)
- >>> mon_instance.affiche_attribut_x()
- 42
- ```
-
- # Méthodes appelant d'autres méthodes
-
- ```python
- class MaClasse:
- def méthode_1(self):
- print("démarrage de la méthode 1")
- print("la méthode 1 affiche bonjour")
- print("bonjour")
- print("fin de la méthode 1")
-
-
- def méthode_2(self):
- print("la méthode 2 appelle la méthode 1")
- self.méthode_1()
- print("fin de la méthode 2")
- ```
-
-
- ```python
- >>> mon_instance = MaClasse()
- >>> mon_instance.méthode_2()
- ```
-
- ```text
- la méthode 2 appelle la méthode 1
- démarrage de la méthode 1
- la méthode 1 affiche bonjour
- bonjour
- fin de la méthode 1
- fin de la méthode 2
- ```
-
- # Constructeur sans arguments
-
- Un constructeur en Python désigne la méthode nomée `__init__`,
- quand celle-ci existe.
-
- La méthode `__init__` est appelée automatiquement quand la
- classe est instanciée:
-
- ```python
- class MaClasse:
- def __init__(self):
- self.x = 1
- self.y = 2
-
- >>> mon_instance = MaClasse()
- >>> mon_instance.x
- 1
- >>> mon_instance.y
- 2
- ```
-
- # Constructeur avec arguments
-
- La méthode `__init__` peut avoir des arguments,
- dans ce cas, ceux ci doivent être fournis
- lors de l'instanciation:
-
- ```python
- class MaClasse:
- def __init__(self, x, y):
- self.x = x
- self.y = y
- ```
-
- ```python
- >>> mon_instance = MaClasse(3, 4)
- >>> mon_instance.x
- 3
- >>> mon_instance.y
- 4
- ```
-
- # Couplage (1)
-
- ## Définition
-
- Un couplage décrit une relation entre deux classes.
-
- ## Exemple
-
- Ici on veut représenter des chats et des humains qui adoptent (on non) des chats.
- Tous les chats ont un nom, et tous les humains ont un prénom.
-
- On peut utiliser pour cela deux classes: `Chat` et `Humain`:
-
- # Couplage (2)
-
-
- ```python
- class Chat:
- def __init__(self, nom):
- self.nom = nom
-
- >>> chat = Chat("Monsieur Moustaches")
- >>> chat.nom
- 'Monsieur Moustaches'
- ```
-
- ```python
- class Humain:
- def __init__(self, prénom):
- self.prénom = prénom
- >>> alice = Humain(prénom="Alice")
- >>> alice.prénom
- "Alice"
- ```
-
- #
-
- Maintenant on veut que les humains puissent adopter des chats.
- Pour cela, on peut rajouter la méthode `adopte` dans la classe
- `Humain`.
-
- Cette méthode va prendre un argument - une instance de la
- classe `Chat`:
-
- ```python
- class Humain:
- def __init__(self, prénom):
- self.prénom = prénom
-
- def adopte(self, chat):
- print(self.prénom, "adopte un chat")
-
- >>> boule_de_poils = Chat("Boule de Poils")
- >>> alice = Humain("Alice")
- >>> alice.adopte(boule_de_poils)
- "Alice adopte un chat"
- ```
-
- #
-
- On peut accéder au nom du chat depuis la méthode `adopte`,
- en utilisant la syntaxe `nom.attribut` vue précédemment:
-
- ```python
- class Humain:
- def __init__(self, prénom):
- self.prénom = prénom
-
- def adopte(self, chat):
- print(self.prénom, "adopte", chat.nom)
-
- >>> boule_de_poils = Chat("Boule de Poils")
- >>> alice = Humain("Alice")
- >>> alice.adopte(boule_de_poils)
- "Alice adopte Boule de Poils"
- ```
-
- # Couplage
-
- ```python
- class Humain:
- ...
- def adopte(self, chat):
- print(self.prénom, "adopte", chat.nom)
- ```
-
- Notez également que nous avons écrit `chat.nom`. ainsi, la méthode `adopte()`
- ne peut être appelée que part une instance qui a un attribut `nom` - sinon
- on aura une erreur.
-
- Donc si on modifie la classe `Chat` et qu'on renomme l'attribut `nom` en `surnom` par exemple,
- la méthode `adopte()` de la classe `Humain` cessera de fonctionner: on dit
- qu'on a un *couplage* entre les classes `Chat` et `Humain`.
-
- # Couplage entre fonctions
-
- ```python
- largeur = demander_largeur()
- dessine_sapin(largeur)
- ```
-
-
- \vfill
-
- * `dessine_sapin()` prend un argument `largeur`, retourné par `demander_largeur()`.
- * `dessine_sapin()` _dépend_ de `demander_largeur()`
-
- # Dépendances entre classes (1)
-
- ```python
- class Chat:
- def __init__(self, nom):
- self.nom = nome
- ```
-
- On ne peut pas construire des chats sans nom:
-
- ```python
- >>> chat = Chat()
- TypeError: __init__() missing 1 required positional
- argument: 'nom'
- ```
-
-
- # Dépendances entre classes (2)
-
- Tous les enfants ont un chat!
-
- ```python
- class Enfant:
- def __init__(self, prénom, chat):
- self.prénom = prénom
- self.chat = chat
-
- >>> alice = Enfant("Alice")
- TypeError: __init__() missing 1 required positional
- argument: 'chat'
-
- >>> boule_de_poils = Chat("Boule de Poils")
- >>> alice = Enfant("Alice", boule_de_poils)
- # OK!
- ```
-
- # Utilisation de la composition
-
-
- ```python
- class Chat:
- def __init__(self, nom):
- self.nom = nom
-
- def ronronne(self):
- print(self.nom, 'fait: "prrrrr"')
-
- def caresse(self):
- self.ronronne()
-
-
- >>> boule_de_poils = Chat("Boule de Poils")
- >>> boule_de_poils.caresse()
- Boule de Poils fait "prrrrr"
- ```
-
- # Composition (2)
-
- ```python
- class Enfant:
- def __init__(self, prénom, chat):
- self.chat = chat
-
- def console(self):
- self.chat.caresse()
-
- >>> boule_de_poils = Chat("Boule de Poils")
- >>> alice = Enfant("Alice", boule_de_poils)
- # Alice est triste, on la console
- >>> alice.console()
- Boule de Poils fait "prrrrr"
- # Alice est consolée :)
- ```
|