You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

python-S02-E07.md 6.8 KiB

4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. % Programmation avec Python (Épisode 7)
  2. % Dimitri Merejkowsky
  3. \center \huge Rappels
  4. # Classes vides
  5. Définition:
  6. ```python
  7. class MaClasse:
  8. pass
  9. ```
  10. Instanciation:
  11. ```python
  12. >>> instance_1 = MaClasse()
  13. ```
  14. # Attributs
  15. Un attribut est une variable _à l'intérieur_ d'autre chose (par exemple une instance de classe).
  16. ```python
  17. >>> mon_instance = MaClasse()
  18. # création de l'attribut `x` dans mon_instance:
  19. >>> mon_instance.x = 42
  20. # accès à l'attribut `x` dans mon_instance:
  21. >>> mon_instance.x
  22. 42
  23. ```
  24. # Méthodes
  25. Une méthode est une fonction définie à l'intérieur d'une classe:
  26. Définition:
  27. ```python
  28. class MaClasse:
  29. def ma_méthode(self):
  30. return 42
  31. ```
  32. Les méthodes sont des attributs des instances de classes:
  33. ```python
  34. class MaClasse:
  35. def ma_méthode(self):
  36. return 42
  37. >>> ma_méthode()
  38. Erreur
  39. >>> mon_instance = MaClasse()
  40. >>> mon_instance.ma_méthode()
  41. 42
  42. ```
  43. # self
  44. `self` *prend la valeur de l'instance courante* quand la méthode est appelée.
  45. ```python
  46. class MaClasse:
  47. def affiche_attribut_x(self):
  48. print(self.x)
  49. >>> mon_instance = MaClasse()
  50. >>> mon_instance.x = 42
  51. >>> mon_instance.affiche_attribut_x()
  52. 42
  53. ```
  54. # self (2)
  55. On peut aussi *créer* des attributs dans une méthode:
  56. ```python
  57. class MaClasse:
  58. def crée_attribut_x(self):
  59. self.x = 42
  60. def affiche_attribut_x(self):
  61. print(self.x)
  62. >>> mon_instance = MaClasse()
  63. >>> mon_instance.affiche_attribut_x()
  64. # Erreur: `mon_instance` n'a pas d'attribut `x`
  65. >>> mon_instance.crée_attribut_x()
  66. >>> mon_instance.affiche_attribut_x()
  67. 42
  68. ```
  69. # Méthodes avec arguments
  70. ```python
  71. class MaClasse
  72. def crée_attribut_x(self, valeur_de_x):
  73. self.x = valeur_de_x
  74. def affiche_attribut_x(self);
  75. print(self.x)
  76. >>> mon_instance = MaClasse()
  77. >>> mon_instance.crée_attribut_x(42)
  78. >>> mon_instance.affiche_attribut_x()
  79. 42
  80. ```
  81. # Méthodes appelant d'autres méthodes
  82. ```python
  83. class MaClasse:
  84. def méthode_1(self):
  85. print("démarrage de la méthode 1")
  86. print("la méthode 1 affiche bonjour")
  87. print("bonjour")
  88. print("fin de la méthode 1")
  89. def méthode_2(self):
  90. print("la méthode 2 appelle la méthode 1")
  91. self.méthode_1()
  92. print("fin de la méthode 2")
  93. ```
  94. ```python
  95. >>> mon_instance = MaClasse()
  96. >>> mon_instance.méthode_2()
  97. ```
  98. ```text
  99. la méthode 2 appelle la méthode 1
  100. démarrage de la méthode 1
  101. la méthode 1 affiche bonjour
  102. bonjour
  103. fin de la méthode 1
  104. fin de la méthode 2
  105. ```
  106. # Constructeur sans arguments
  107. Un constructeur en Python désigne la méthode nomée `__init__`,
  108. quand celle-ci existe.
  109. La méthode `__init__` est appelée automatiquement quand la
  110. classe est instanciée:
  111. ```python
  112. class MaClasse:
  113. def __init__(self):
  114. self.x = 1
  115. self.y = 2
  116. >>> mon_instance = MaClasse()
  117. >>> mon_instance.x
  118. 1
  119. >>> mon_instance.y
  120. 2
  121. ```
  122. # Constructeur avec arguments
  123. La méthode `__init__` peut avoir des arguments,
  124. dans ce cas, ceux ci doivent être fournis
  125. lors de l'instanciation:
  126. ```python
  127. class MaClasse:
  128. def __init__(self, x, y):
  129. self.x = x
  130. self.y = y
  131. ```
  132. ```python
  133. >>> mon_instance = MaClasse(3, 4)
  134. >>> mon_instance.x
  135. 3
  136. >>> mon_instance.y
  137. 4
  138. ```
  139. # Couplage (1)
  140. ## Définition
  141. Un couplage décrit une relation entre deux classes.
  142. ## Exemple
  143. Ici on veut représenter des chats et des humains qui adoptent (on non) des chats.
  144. Tous les chats ont un nom, et tous les humains ont un prénom.
  145. On peut utiliser pour cela deux classes: `Chat` et `Humain`:
  146. # Couplage (2)
  147. ```python
  148. class Chat:
  149. def __init__(self, nom):
  150. self.nom = nom
  151. >>> chat = Chat("Monsieur Moustaches")
  152. >>> chat.nom
  153. 'Monsieur Moustaches'
  154. ```
  155. ```python
  156. class Humain:
  157. def __init__(self, prénom):
  158. self.prénom = prénom
  159. >>> alice = Humain(prénom="Alice")
  160. >>> alice.prénom
  161. "Alice"
  162. ```
  163. #
  164. Maintenant on veut que les humains puissent adopter des chats.
  165. Pour cela, on peut rajouter la méthode `adopte` dans la classe
  166. `Humain`.
  167. Cette méthode va prendre un argument - une instance de la
  168. classe `Chat`:
  169. ```python
  170. class Humain:
  171. def __init__(self, prénom):
  172. self.prénom = prénom
  173. def adopte(self, chat):
  174. print(self.prénom, "adopte un chat")
  175. >>> boule_de_poils = Chat("Boule de Poils")
  176. >>> alice = Humain("Alice")
  177. >>> alice.adopte(boule_de_poils)
  178. "Alice adopte un chat"
  179. ```
  180. #
  181. On peut accéder au nom du chat depuis la méthode `adopte`,
  182. en utilisant la syntaxe `nom.attribut` vue précédemment:
  183. ```python
  184. class Humain:
  185. def __init__(self, prénom):
  186. self.prénom = prénom
  187. def adopte(self, chat):
  188. print(self.prénom, "adopte", chat.nom)
  189. >>> boule_de_poils = Chat("Boule de Poils")
  190. >>> alice = Humain("Alice")
  191. >>> alice.adopte(boule_de_poils)
  192. "Alice adopte Boule de Poils"
  193. ```
  194. # Couplage
  195. ```python
  196. class Humain:
  197. ...
  198. def adopte(self, chat):
  199. print(self.prénom, "adopte", chat.nom)
  200. ```
  201. Notez également que nous avons écrit `chat.nom`. ainsi, la méthode `adopte()`
  202. ne peut être appelée que part une instance qui a un attribut `nom` - sinon
  203. on aura une erreur.
  204. Donc si on modifie la classe `Chat` et qu'on renomme l'attribut `nom` en `surnom` par exemple,
  205. la méthode `adopte()` de la classe `Humain` cessera de fonctionner: on dit
  206. qu'on a un *couplage* entre les classes `Chat` et `Humain`.
  207. # Couplage entre fonctions
  208. ```python
  209. largeur = demander_largeur()
  210. dessine_sapin(largeur)
  211. ```
  212. \vfill
  213. * `dessine_sapin()` prend un argument `largeur`, retourné par `demander_largeur()`.
  214. * `dessine_sapin()` _dépend_ de `demander_largeur()`
  215. # Dépendances entre classes (1)
  216. ```python
  217. class Chat:
  218. def __init__(self, nom):
  219. self.nom = nome
  220. ```
  221. On ne peut pas construire des chats sans nom:
  222. ```python
  223. >>> chat = Chat()
  224. TypeError: __init__() missing 1 required positional
  225. argument: 'nom'
  226. ```
  227. # Dépendances entre classes (2)
  228. Tous les enfants ont un chat!
  229. ```python
  230. class Enfant:
  231. def __init__(self, prénom, chat):
  232. self.prénom = prénom
  233. self.chat = chat
  234. >>> alice = Enfant("Alice")
  235. TypeError: __init__() missing 1 required positional
  236. argument: 'chat'
  237. >>> boule_de_poils = Chat("Boule de Poils")
  238. >>> alice = Enfant("Alice", boule_de_poils)
  239. # OK!
  240. ```
  241. # Utilisation de la composition
  242. ```python
  243. class Chat:
  244. def __init__(self, nom):
  245. self.nom = nom
  246. def ronronne(self):
  247. print(self.nom, 'fait: "prrrrr"')
  248. def caresse(self):
  249. self.ronronne()
  250. >>> boule_de_poils = Chat("Boule de Poils")
  251. >>> boule_de_poils.caresse()
  252. Boule de Poils fait "prrrrr"
  253. ```
  254. # Composition (2)
  255. ```python
  256. class Enfant:
  257. def __init__(self, prénom, chat):
  258. self.chat = chat
  259. def console(self):
  260. self.chat.caresse()
  261. >>> boule_de_poils = Chat("Boule de Poils")
  262. >>> alice = Enfant("Alice", boule_de_poils)
  263. # Alice est triste, on la console
  264. >>> alice.console()
  265. Boule de Poils fait "prrrrr"
  266. # Alice est consolée :)
  267. ```