@@ -1,2 +1,5 @@ | |||
explication des exercices | |||
insérer exercices pour chaque épisode de la saison 2 | |||
Explications sur `globals()` et `locals()` |
@@ -74,3 +74,18 @@ et on peut utiliser des parenthèses pour grouper les opérations:: | |||
print((1 + 2) * 3) | |||
# affiche: 9 | |||
Combiner opération et assignation | |||
---------------------------------- | |||
La notation ``+=`` permet de combiner addition et assignation:: | |||
x = 3 | |||
x = x + 1 | |||
print(x) | |||
# affiche :: 4 | |||
x = 3 | |||
x += 1 | |||
print(x) | |||
# affiche :: 4 |
@@ -0,0 +1,72 @@ | |||
Chapitre 4 - Booléens et conditions | |||
=================================== | |||
En Python, les variables ``True`` et ``False`` sont toujours définies | |||
et servent à représenter une valeur vraie ou fausse. | |||
(Notez qu'elles commencent par une majuscule) | |||
Assignation | |||
----------- | |||
On peut assigner des variables à True ou False:: | |||
la_terre_est_plate = False | |||
python_c_est_genial = True | |||
Comparaisons | |||
------------ | |||
Certaines opérations renvoient des booléens: | |||
+------+-----------------------------+ | |||
|``=`` | égal | | |||
+------+-----------------------------+ | |||
|``!=``| différent | | |||
+------+-----------------------------+ | |||
|``>`` | strictement supérieur | | |||
+------+-----------------------------+ | |||
|``>=``| supérieur ou égal | | |||
+------+-----------------------------+ | |||
|``<`` | strictement inférieur | | |||
+------+-----------------------------+ | |||
|``<=``| inférieur | | |||
+------+-----------------------------+ | |||
Par example:: | |||
a = 2 | |||
b = 3 | |||
print(a > b) | |||
# affiche: False | |||
print(2 + 2 == 4) | |||
# affiche: True | |||
.. warning:: | |||
Ne pas confondre: ``==`` pour la comparaison et ``=`` pour l'assignation | |||
Enfin, on peut écrire des encadrements:: | |||
a = 3 | |||
print(2 <= a < 4) | |||
# affiche: True | |||
not | |||
--- | |||
Enfin, on peut utiliser ``not`` pour inverser une condition:: | |||
a = 3 | |||
if not a == 4: | |||
print("a est différent de 4") | |||
# affiche: a est différent de 4 | |||
la_terre_est_plate = False | |||
print(not la_terre_est_plate) | |||
# affiche: True |
@@ -1,98 +0,0 @@ | |||
Chapitre 4 - code source | |||
======================== | |||
Non persistance des variables | |||
------------------------------ | |||
.. code-block:: console | |||
$ python3 | |||
>>> a = 2 | |||
>>> quit() | |||
``` | |||
.. code-block:: console | |||
$ python3 | |||
>>> a | |||
Traceback (most recent call last): | |||
File "<stdin>", line 1, in <module> | |||
NameError: name 'a' is not defined | |||
Du code dans un fichier | |||
----------------------- | |||
Aussi appelé: "code source", ou "source". | |||
L'essence du logiciel libre :) | |||
Installation d'un éditeur de texte simple | |||
------------------------------------------ | |||
* Linux; ``gedit``, ``kate``, ... | |||
* macOS: ``CotEditor`` | |||
* Windows: ``Notepad++`` | |||
J'insiste sur **simple**. Inutile d'installer un IDE pour le moment. | |||
Configuration | |||
------------- | |||
* Police de caractères à chasse fixe | |||
* Indentation de *4 espaces* | |||
* Remplacer tabulation par des espaces | |||
* Activer la coloration syntaxique | |||
Notre premier fichier source | |||
----------------------------- | |||
Insérez le code suivant dans votre éditeur de texte | |||
.. code-block:: python | |||
# Affiche un message | |||
print("Bonjour, monde") | |||
Sauvegardez dans un fichier `bonjour.py` dans `Documents/e2l/python` par exemple | |||
Lancer du code en ligne de commande | |||
----------------------------------- | |||
.. code-block:: console | |||
cd Documents/e2l/python/ | |||
python3 bonjour.py | |||
Bonjour, monde | |||
* Les lignes commençant par dièse (``#``) ont été ignorées - ce sont des *commentaires*. | |||
* ``print()`` affiche la valeur, comme dans le REPL. | |||
Note importante | |||
--------------- | |||
Vous avez juste besoin: | |||
* d'un éditeur de texte | |||
* de Python3 installé | |||
* d'une ligne de commande | |||
Pas la peine d'installer quoique ce soit de plus pour le moment | |||
1. *Recopiez* le code affiché dans votre éditeur, à la suite du code | |||
déjà écrit | |||
2. Lancez le code depuis la ligne de commande | |||
3. Réparez les erreurs éventuelles | |||
4. Recommencez | |||
@@ -1,25 +1,36 @@ | |||
Flot de contrôle | |||
================ | |||
L'essence de la programmation! | |||
Pour l'instant, toutes les instructions que nous avons | |||
écrites ont été exécutée une par une et dans l'ordre | |||
d'apparition dans le code source. | |||
Modifier l'ordre d'exécution de ces lignes s'appelle modifier le flot de | |||
contrôle, et c'est l'essence de la programmation! | |||
if | |||
-- | |||
++ | |||
.. code-block:: python | |||
On peut utiliser le mot ``if`` pour autoriser ou empécher | |||
l'éxcution du code en-dessous:: | |||
a = 3 | |||
b = 4 | |||
if a == b: | |||
print("a et b sont égaux") | |||
print("on continue") | |||
# affiche juste | |||
# on continue | |||
La 4ème ligne n'est pas éxécutée parce la condition | |||
est fausse. | |||
Notes: | |||
* deux points à la fin de la ligne | |||
* indentation après les deux points | |||
* il y a le caractère ``:`` (deux points) à la fin de la ligne | |||
* le code en-dessous du ``if`` commence par 4 espaces: on appelle | |||
cela une *indentation* | |||
* si la condition n'est pas vraie, rien ne se passe | |||
Notez qu'on peut mettre uniquement une variable ou une valeur | |||
@@ -27,14 +38,25 @@ après le if. Ceci ne fonctionne pas:: | |||
if a = 3: | |||
print("a égale 3") | |||
# affiche: SyntaxError | |||
On parle aussi de "bloc" si plusieurs lignes sont identées:: | |||
et fait une erreur de syntaxe | |||
a = 3 | |||
b = 4 | |||
if a == b: | |||
# début du bloc | |||
print("a et b sont égaux") | |||
c = 2 * a | |||
# fin du block | |||
print("on continue") | |||
if / else | |||
--------- | |||
.. code-block:: | |||
On peut utiliser le mot ``else`` après un condition en ``if`` | |||
pour éxécutér un bloc si la condition est fausse:: | |||
a = 3 | |||
b = 4 | |||
@@ -42,52 +64,58 @@ if / else | |||
print("a et b sont égaux") | |||
else: | |||
print("a et b sont différent") | |||
# affiche: a et b sont différents | |||
if / elif | |||
--------- | |||
.. code-block:: | |||
On peut utiliser ``if``, ``elif`` et ``else`` pour enchaîner plusieurs | |||
conditions:: | |||
age = 23 | |||
if age < 10: | |||
print("inférieur à dix") | |||
print("âge inférieur à dix") | |||
elif 10 <= age < 20: | |||
print("âge entre 10 et 20") | |||
elif 20 <= age < 40: | |||
print("âge entre 20 et 40") | |||
else: | |||
print("âge supérieur à 40") | |||
On peut mettre autont de `elif` qu'on veut! | |||
Le derier `else` s'éxécute en dernier | |||
# affiche: âge entre 20 et 40 | |||
while | |||
----- | |||
Répéter tant qu'une condition est vraie:: | |||
On peut utiliser ``while`` pour répéter un bloc tant qu'une condition | |||
est vraie:: | |||
i = 0 | |||
while i < 3: | |||
print(i) | |||
i = i + 1 | |||
.. code-block:: console | |||
.. code-block:: text | |||
0 | |||
1 | |||
2 | |||
Notez que la variable ``i`` passe par plusieurs valeurs différentes. | |||
Notre première boucle infinie | |||
----------------------------- | |||
Boucle infinie | |||
-------------- | |||
.. code-block:: | |||
On parle de *boucle infinie* si la condition ne devient jamais fausse:: | |||
while True: | |||
print("spam!") | |||
CTRL-C pour interrompre | |||
Dans ce cas, il faut appuyer sur ``CTRL-C`` pour interrompre | |||
le programme. | |||
Notez ici qu'on a mis directement la valeur ``True``, et non une comparaison. | |||
Combiner while et if | |||
@@ -11,15 +11,23 @@ Définition:: | |||
* avec `def` | |||
* avec un `:` à la fin et un *bloc indenté* (appelé le "corps") | |||
* avec un `:` à la fin et un *bloc indenté* (appelé *le corps de la fonction*). | |||
Appel:: | |||
>>> dire_bonjour() | |||
Bonjour | |||
dire_bonjour() | |||
* avec le nom de la fonction et des parenthèses | |||
Example complet:: | |||
def dire_bonjour(): | |||
print("Bonjour") | |||
bonjour() | |||
# Affiche: bonjour' | |||
Le pouvoir des fonctions | |||
------------------------ | |||
@@ -35,6 +43,7 @@ programmation. | |||
Fonction avec un argument | |||
-------------------------- | |||
Définition: avec l'argument à l'intérieur des parenthèses:: | |||
@@ -43,17 +52,10 @@ Définition: avec l'argument à l'intérieur des parenthèses:: | |||
Appel: en passant une variable ou une valeur dans les parenthèses:: | |||
>>> dire_bonjour("Germaine") | |||
Bonjour Germaine | |||
>>> prénom_de_charlotte = "Charlotte" | |||
>>> dire_bonjour(prénom_de_charlotte) | |||
Bonjour Charlotte | |||
Exécution d'une fonction | |||
------------------------ | |||
dire_bonjour("Germaine") | |||
C'est exatement comme si on assignait les arguments de la fonction avant d'éxécuter le code | |||
L'éxécution de l'appel à une foctionne exactement comme si on assignait | |||
les arguments de la fonction avant d'éxécuter le code | |||
dans le corps:: | |||
# Ceci: | |||
@@ -65,3 +67,16 @@ dans le corps:: | |||
# Lui-même équivalent à: | |||
print("Bonjour " + "Dimitri") | |||
Example complet:: | |||
def dire_bonjour(prénom): | |||
print("Bonjour " + prénom) | |||
dire_bonjour("Germaine") | |||
# affiche: Bonjour Germaine | |||
prénom_de_charlotte = "Charlotte" | |||
dire_bonjour(prénom_de_charlotte) | |||
# affiche: Bonjour Charlotte | |||
@@ -22,8 +22,8 @@ Les variables en dehors des fonctions sont disponibles partout:: | |||
Une variable peut avoir en "cacher" une autre si elle a une portée différente:: | |||
def dire_bonjour(prénom): | |||
print("Bonjour " + prénom) # portée: uniquement dans | |||
# le corps dire_bonjour | |||
print("Bonjour " + prénom) # portée: uniquement dans | |||
# le corps dire_bonjour | |||
prénom = "Dimitri" # portée: dans tout le programme | |||
prénom = "Dimitri" # portée: dans tout le programme | |||
dire_bonjour(prénom) # Ok |
@@ -11,9 +11,11 @@ On peut aussi mettre des valeurs par défaut:: | |||
Appel:: | |||
>>> dire_bonjour("Thomas", enthousiaste=True) | |||
Bonjour Thomas! | |||
>>> dire_bonjour("Thomas", enthousiaste=False) | |||
Bonjour Thomas | |||
>>> dire_bonjour("Thomas") | |||
Bonjour Thomas | |||
dire_bonjour("Thomas", enthousiaste=True) | |||
# affiche: Bonjour Thomas! | |||
dire_bonjour("Thomas", enthousiaste=False) | |||
# affiche: Bonjour Thomas | |||
dire_bonjour("Thomas") | |||
# affiche: Bonjour Thomas |
@@ -18,19 +18,31 @@ On peut passer autant d'arguments qu'on veut à ``print`` et: | |||
* Il les sépare par des espaces | |||
* Ajoute un retour à la ligne à la fin:: | |||
>>> prénom = "Charlotte" | |||
prénom = "Charlotte" | |||
print("Bonjour", pŕenom) | |||
print("Ça va ?") | |||
.. code-block:: text | |||
Bonjour Charlotte | |||
Ça va ? | |||
On peut demander à `print` de changer son séparateur:: | |||
>>> a = "chauve" | |||
>>> b = "souris" | |||
>>> print(a, b, sep="-") | |||
a = "chauve" | |||
b = "souris" | |||
print(a, b, sep="-") | |||
.. code-block:: text | |||
chauve-souris | |||
Ou de changer le caractère de fin:: | |||
>>> print("Ceci tient", end="") | |||
>>> print("sur une seule ligne") | |||
Ceci tient sur une seule ligne | |||
print("Ceci tient", end="") | |||
print("sur une seule ligne") | |||
.. code-block:: text | |||
Ceci tient sur une seule ligne |
@@ -26,9 +26,17 @@ corps de la fonction:: | |||
return | |||
print("Heureux de faire votre connaissance") | |||
>>> dire_bonjour("Dimitri", première_fois=True) | |||
dire_bonjour("Dimitri", première_fois=True) | |||
.. code-block:: text | |||
Bonjour Dimitri | |||
Heureux de faire votre connaissance | |||
>>> dire_bonjour("Dimitri", première_fois=False) | |||
.. code-block:: python | |||
dire_bonjour("Dimitri", première_fois=False) | |||
.. code-block:: text | |||
Bonjour Dimitri |
@@ -33,41 +33,48 @@ Connaître la taille d'une liste | |||
Avec ``len()`` - encore une fonction native:: | |||
>>> liste_vide = [] | |||
>>> len(liste_vide) | |||
0 | |||
>>> trois_entiers = [1, 2, 3] | |||
>>> len(trois_entiers) | |||
3 | |||
liste_vide = [] | |||
taille = len(liste_vide) | |||
print(taille) | |||
# affiche: 0 | |||
trois_entiers = [1, 2, 3] | |||
taille = len(trois_entiers) | |||
print(taille) | |||
# affiche: 3 | |||
Concaténation de listes | |||
----------------------- | |||
Avec ``+``:: | |||
>>> prénoms = ["Alice", "Bob"] | |||
>>> prénoms += ["Charlie", "Eve"] | |||
>>> prénoms | |||
['Alice', 'Bob', "Charlie", 'Eve'] | |||
prénoms = ["Alice", "Bob"] | |||
prénoms += ["Charlie", "Eve"] | |||
print(prénoms) | |||
# affiche: ['Alice', 'Bob', "Charlie", 'Eve'] | |||
On ne peut concaténer des listes que avec d'autres listes:: | |||
>>> scores = [1, 2, 3] | |||
>>> scores += 4 # TypeError | |||
>>> scores += [4] # OK | |||
scores = [1, 2, 3] | |||
scores += 4 | |||
# erreur | |||
scores += [4] | |||
print(scores) | |||
# affiche: [1,2,3,4] | |||
Test d'appartenance | |||
------------------- | |||
Avec ``in``:: | |||
>>> prénoms = ["Alice", "Bob"] | |||
>>> "Alice" in prénoms | |||
True | |||
prénoms = ["Alice", "Bob"] | |||
print("Alice" in prénoms) | |||
# affiche: True | |||
>>> prénoms = ["Alice", "Bob"] | |||
>>> "Charlie" in prénoms | |||
False | |||
prénoms = ["Alice", "Bob"] | |||
print("Charlie" in prénoms) | |||
# affiche: False | |||
Itérer sur les élements d'une liste | |||
------------------------------------ | |||
@@ -80,35 +87,43 @@ Avec ``for ... in``:: | |||
# élément de la liste | |||
print("Bonjour", prénom) | |||
.. code-block:: text | |||
Bonjour Alice | |||
Bonjour Bob | |||
Bonjour Charlie | |||
## Indéxer une liste | |||
Indéxer une liste | |||
------------------ | |||
* Avec `[]` et un entier | |||
* Avec ``[]`` et un entier | |||
* Les index valides vont de 0 à `n-1` où `n` est la | |||
* Les index valides vont de 0 à ``n-1`` où ``n`` est la | |||
taille de la liste:: | |||
>>> fruits = ["pomme", "orange", "poire"] | |||
>>> fruits[0] | |||
"pomme" | |||
>>> fruits[1] | |||
"orange" | |||
>>> list[2] | |||
"poire" | |||
>>> fruits[3] # IndexError | |||
fruits = ["pomme", "orange", "poire"] | |||
print(fruits[0]) | |||
# affiche: "pomme" | |||
print(fruits[1]) | |||
# affiche: "orange" | |||
print(list[2]) | |||
# affiche: "poire" | |||
fruits[3] | |||
# erreur: IndexError | |||
Modifier une liste | |||
------------------- | |||
Encore une assignation:: | |||
>>> fruits = ["pomme", "orange", "poire"] | |||
>>> fruits[0] = "abricot" | |||
>>> fruits | |||
["abricot", "orange", "poire"] | |||
fruits = ["pomme", "orange", "poire"] | |||
fruits[0] = "abricot" | |||
print(fruits) | |||
# affiche: ["abricot", "orange", "poire"] | |||
Les strings sont aussi des listes (presque) | |||
-------------------------------------------- | |||
@@ -128,17 +143,45 @@ On peut itérer sur les caractères d'une string:: | |||
On peut tester si un caractère est présent:: | |||
>>> "e" in "vache" | |||
True | |||
>>> "x" in "vache" | |||
False | |||
print("e" in "vache") | |||
# affiche: True | |||
print(x" in "vache") | |||
# affiche: False | |||
Mais on neut peut pas modifier une string:: | |||
>>> prénom = "Charlotte" | |||
>>> prénom[0] | |||
"C" | |||
>>> prénom[3] | |||
"r" | |||
>>> prénom[0] = "X" # TypeError | |||
prénom = "Charlotte" | |||
l = prénom[0] | |||
print(l) | |||
# affiche: "C" | |||
l = prénom[3] | |||
print(l) | |||
# affiche: "r" | |||
prénom[0] = "X" | |||
# erreur: TypeError | |||
Falsy et truthy | |||
---------------- | |||
En réalité on peut mettre autre chose qu'une comparaison ou une variable booléenne après le if. | |||
Si on met une liste vide, ``if`` se comportera comme si on avait mis une valeur fausse, et si | |||
la liste n'est pas vide , ``if`` se comportera comme si on avait mis une valeur vraie.:: | |||
ma_liste = [1, 2, 3] | |||
if ma_liste: | |||
print("ma_liste n'est pas vide") | |||
# affiche: ma_liste n'est pas vide | |||
mon_autre_liste = [] | |||
if not mon_autre_liste: | |||
print("mon_autre_liste est vide") | |||
# affiche: mon_autre_liste est vide | |||
On dit que les listes vides sont *Falsy* et les listes non-vides *Truthy* |
@@ -8,17 +8,6 @@ Définition | |||
Un peu comme ``True`` et ``False`` qui sont deux valeurs qui servent à représenter tous les booléens. | |||
Représenter l'absence | |||
---------------------- | |||
L'interpréteur intéractif n'affiche rien quand la valeur est None:: | |||
>>> a = 42 | |||
>>> a | |||
42 | |||
>>> b = None | |||
>>> b | |||
Retourner None | |||
---------------- | |||
@@ -26,11 +15,12 @@ En réalité, *toutes* les fonctions pythons retournent *quelque chose*, même q | |||
elle ne contiennent pas le mot-clé ``return``.:: | |||
def ne_renvoie_rien(): | |||
print("je ne fais qu'afficher quelque chose") | |||
x = 2 | |||
>>> resultat = ne_renvoie_rien() | |||
"je ne fais qu'afficher quelque chose" | |||
>>> resultat | |||
resultat = ne_renvoie_rien() | |||
print(resultat) | |||
# affiche: None | |||
Opérations avec None | |||
--------------------- | |||
@@ -38,17 +28,26 @@ Opérations avec None | |||
La plupart des fonctions que nous avons vues échouent si on leur passe ``None`` | |||
en argument:: | |||
>>> len(None) | |||
TypeError: object of type 'NoneType' has no len() | |||
>>> None < 3 | |||
TypeError: '<' not supported between instances of | |||
'NoneType' and 'int' | |||
>>> int(None) | |||
TypeError: int() argument must be a string, | |||
a bytes-like object or a number, | |||
not 'NoneType' | |||
>>> str(None) | |||
'None' | |||
x = len(None) | |||
# erreur: TypeError | |||
x = None < 3 | |||
# erreur: TypeError | |||
x = int(None) | |||
# erreur: TypeError | |||
Mais ``str`` fonctionne:: | |||
x = str(None) | |||
print(x) | |||
# affiche: 'None' | |||
On peut vérifier si une variable vaut ``None`` avec ``is None``:: | |||
x = ne_renvoie_rien() | |||
print(x is None) | |||
# affiche: True | |||
Example d'utilisation | |||
---------------------- | |||
@@ -61,20 +60,10 @@ Example d'utilisation | |||
return element | |||
return None | |||
>>> trouve_dans_liste(2, [1, 2, 3]) | |||
2 | |||
>>> trouve_dans_liste(False, [True, False]) | |||
False | |||
>>> trouve_dans_liste(1, [3, 4]) | |||
None est Falsy, et on peut vérifier si une variable vaut ``None`` avec ``is None``:: | |||
x = trouve_dans_liste(2, [1, 2, 3]) | |||
print(x) | |||
# affiche: 2 | |||
# hypothèse: `ma_valeur` n'est pas None | |||
mon_element = trouve_dans_liste(ma_valeur, ma_liste) | |||
if mon_element is None: | |||
print("élément absent de la liste") | |||
if not mon_element: | |||
# Peut-être que l'élément n'était pas dans la liste, | |||
# ou peut-être y était-il, mais avec une valeur falsy | |||
... | |||
x = trouve_dans_liste(1, [3, 4]) | |||
print(x) | |||
# affiche: None |
@@ -31,49 +31,57 @@ Accès aux valeurs | |||
Avec ``[]``, comme pour les listes, mais avec une *clé* à la place d'un *index*:: | |||
>>> scores = {"john": 10, "bob": 42} | |||
>>> scores["john"] | |||
10 | |||
>>> scores["bob"] | |||
42 | |||
>>> scores["charlie"] | |||
KeyError | |||
scores = {"john": 10, "bob": 42} | |||
print(scores["john"]) | |||
# affiche: 10 | |||
print(scores["bob"]) | |||
# affiche: 42 | |||
print(scores["charlie"]) | |||
# erreur: KeyError | |||
Test d'appartenance | |||
--------------------- | |||
Avec ``in``, comme le listes:: | |||
>>> scores = {"john": 10, "bob": 42} | |||
>>> "charlie" in scores | |||
False | |||
scores = {"john": 10, "bob": 42} | |||
print("charlie" in scores) | |||
# affiche: False | |||
Modifier la valeur d'une clé | |||
----------------------------- | |||
Comme pour les listes, avec une assignation:: | |||
>>> scores = {"john": 10, "bob": 42} | |||
>>> scores["john"] = 20 | |||
>>> scores | |||
{"john": 20, "bob": 42} | |||
scores = {"john": 10, "bob": 42} | |||
scores["john"] = 20 | |||
print(scores) | |||
# affiche: {"john": 20, "bob": 42} | |||
Créer une nouvelle clé | |||
----------------------- | |||
Même méchanisme que pour la modification des clés existantes:: | |||
Même mécanisme que pour la modification des clés existantes:: | |||
scores = {"john": 10, "bob": 42} | |||
scores["charlie"] = 30 | |||
print(scores) | |||
# affiche: {"john": 20, "bob": 42, "charlie": 30} | |||
>>> scores = {"john": 10, "bob": 42} | |||
>>> scores["charlie"] = 30 | |||
>>> scores | |||
{"john": 20, "bob": 42, "charlie": 30} | |||
*rappel*: ceci ne fonctionne pas avec les listes: on ne peut | |||
pas "créer" de nouveaux éléments dans la liste juste | |||
avec un index:: | |||
*rappel*: ceci ne fonctionne pas avec les listes!:: | |||
>>> ma_liste = ["a", "b"] | |||
>>> ma_liste[1] = "c" # ok | |||
["a", "c"] | |||
>>> ma_liste[3] = "d" | |||
IndexError | |||
ma_liste = ["a", "b"] | |||
ma_liste[1] = "c" | |||
print(ma_liste) | |||
# affiche: ["a", "c"] | |||
ma_liste[3] = "d" | |||
# erreur: IndexError | |||
Itérer sur les clés | |||
------------------- | |||
@@ -84,8 +92,14 @@ Avec ``for ... in ...``, comme pour les listes:: | |||
for nom in scores: | |||
# `nom` est assigné à "john" puis "bob" | |||
score_associé_au_nom = scores[nom] | |||
# score_associé_au_nom est assigné à '10' puis '42' | |||
print(nom, score_associé_au_nom) | |||
.. code-block:: | |||
john 10 | |||
bob 42 | |||
del | |||
--- | |||
@@ -94,83 +108,31 @@ Détruire une clé | |||
Avec ``del`` - un nouveau mot-clé:: | |||
>>> scores = {"john": 10, "bob": 42} | |||
>>> del scores["bob"] | |||
>>> scores | |||
{"john": 10} | |||
scores = {"john": 10, "bob": 42} | |||
del scores["bob"] | |||
print(scores) | |||
# affiche: {"john": 10} | |||
Détruire un élément d'une liste | |||
++++++++++++++++++++++++++++++++ | |||
Aussi avec ``del``:: | |||
>>> fruits = ["pomme", "banane", "poire"] | |||
>>> del fruits[1] | |||
>>> fruits | |||
["pomme", "poire"] | |||
fruits = ["pomme", "banane", "poire"] | |||
del fruits[1] | |||
print(fruits) | |||
# affiche: ["pomme", "poire"] | |||
Détruire une variable | |||
+++++++++++++++++++++ | |||
Encore et toujours ``del``:: | |||
>>> mon_entier = 42 | |||
>>> mon_entier += 3 | |||
>>> mon_entier | |||
45 | |||
>>> del mon_entier | |||
>>> mon_entier == 45 | |||
NameError: name 'mon_entier' is not defined | |||
Des dictionnaires partout | |||
--------------------------- | |||
Les variables globales d'un programme Python sont dans un dictionnaire, | |||
accessible avec la fonction native `globals()`:: | |||
$ python3 | |||
>>> globals() | |||
{ | |||
... | |||
'__doc__': None, | |||
'__name__': '__main__', | |||
... | |||
} | |||
On reparlera de `__doc__` et `__name__` un autre jour ...:: | |||
$ python3 | |||
>>> a = 42 | |||
>>> globals() | |||
{ | |||
... | |||
'__doc__': None, | |||
'__name__': '__main__', | |||
... | |||
'a': 42 | |||
} | |||
``` | |||
.. code-block:: | |||
python | |||
$ python3 | |||
>>> a = 42 | |||
>>> del globals()["a"] | |||
>>> a | |||
NameError: name 'a' is not defined | |||
On peut accéder aux variables locales d'une fonction avec ``locals()``:: | |||
def ma_fonction(): | |||
a = 42 | |||
b = 3 | |||
c = a + b | |||
print(locals()) | |||
>>> ma_fonction() | |||
{'a': 42, 'b': 3, 'c': 45} | |||
mon_entier = 42 | |||
mon_entier += 3 | |||
print(mon_entier) | |||
# affiche: 45 | |||
En revanche, il n'est pas conseillé de modifier le dictionaire renvoyé par ``locals()`` ... | |||
del mon_entier | |||
mon_entier += 1 | |||
# erreur: NameError |
@@ -35,10 +35,11 @@ Accès | |||
Avec ``[]`` et l'index de l'élément dans le tuple:: | |||
mon_tuple = (42, "bonjour") | |||
mon_tuple[0] | |||
42 | |||
mon_tuple[1] | |||
"bonjour" | |||
print(mon_tuple[0]) | |||
# affiche: 42 | |||
print(mon_tuple[1]) | |||
# affiche: "bonjour" | |||
Modification | |||
------------ | |||
@@ -47,7 +48,7 @@ Interdit:: | |||
mon_tuple = (42, "bonjour") | |||
mon_tuple[0] = 44 | |||
TypeError: 'tuple' object does not support item assignment | |||
# erreur: TypeError: 'tuple' object does not support item assignment | |||
Test d'appartenance | |||
@@ -55,26 +56,28 @@ Test d'appartenance | |||
Avec ``in``: | |||
>>> mon_tuple = (42, 14) | |||
>>> 42 in mon_tuple | |||
True | |||
mon_tuple = (42, 14) | |||
print(42 in mon_tuple) | |||
# affiche: True | |||
print(14 in mon_tuple) | |||
# affiche: True | |||
>>> 14 in mon_tuple | |||
True | |||
>>> 13 in mon_tuple | |||
False | |||
print(13 in mon_tuple) | |||
# affiche: False | |||
Déstructuration | |||
---------------- | |||
Créer plusieurs variables en une seule ligne:: | |||
>>> couple = ("Batman", "Robin") | |||
>>> héros, side_kick = couple | |||
>>> héros | |||
'Batman' | |||
>>> side_kick | |||
'Robin' | |||
couple = ("Batman", "Robin") | |||
héros, side_kick = couple | |||
print(héros) | |||
# affiche: Batman | |||
print(side_kick) | |||
# affiche: Robin | |||
Quelques erreurs classiques | |||
@@ -82,15 +85,15 @@ Quelques erreurs classiques | |||
.. code-block:: python | |||
>>> héros, side_kick, ennemi = couple | |||
ValueError (3 != 2) | |||
héros, side_kick, ennemi = couple | |||
# erreur: ValueError (3 != 2) | |||
>>> (héros,) = couple | |||
ValueError (1 != 2) | |||
(héros,) = couple | |||
# erreur: ValueError (1 != 2) | |||
# Gare à la virgule: | |||
>>> héros, = couple | |||
ValueError (1 != 2) | |||
héros, = couple | |||
# erreur: ValueError (1 != 2) | |||
Pièges | |||
------ | |||
@@ -110,16 +113,19 @@ Pièges | |||
On peut aussi déstructurer des listes:: | |||
>>> fruits = ["pomme", "banane", "orange"] | |||
>>> premier, deuxième, troisième = fruits | |||
>>> premier | |||
"pomme" | |||
>>> deuxième | |||
"banane" | |||
>>> troisième | |||
"orange" | |||
fruits = ["pomme", "banane", "orange"] | |||
premier, deuxième, troisième = fruits | |||
print(premier) | |||
# affiche: pomme | |||
print(deuxième) | |||
# affiche: banane | |||
print(troisième) | |||
# affiche: orange | |||
On dit aussi: unpacking | |||
On dit aussi: *unpacking* | |||
Utilisations des tuples | |||
------------------------ | |||
@@ -147,6 +153,6 @@ Pour retourner plusieurs valeurs:: | |||
v, c = tire_carte() | |||
print(v, "de", c) | |||
# 10 de trèfle | |||
# affiche: 10 de trèfle | |||
Ce n'est pas une nouvelle syntaxe, juste de la manipulation de tuples! |
@@ -105,14 +105,14 @@ Le code suivant fait exactement la même chose, mais avec une ligne de moins:: | |||
On peut *créer* des attributs dans *n'importe quel instance*, en utilisant l'*assignation*:: | |||
>>> mon_instance = MaClasse() | |||
mon_instance = MaClasse() | |||
# Création de l'attribut `x` dans `mon_instance` | |||
>>> mon_instance.x = 42 | |||
mon_instance.x = 42 | |||
# Accés à l'attribut `x` dans `mon_instance` | |||
>>> mon_instance.mon_attribut | |||
42 | |||
print(mon_instance.mon_attribut) | |||
# affiche: 42 | |||
Méthodes - définition | |||
---------------------- | |||
@@ -135,12 +135,14 @@ la classe:: | |||
class MaClasse: | |||
def ma_méthode(self): | |||
return 42 | |||
>>> ma_méthode() | |||
Erreur | |||
>>> mon_instance = MaClasse() | |||
>>> mon_instance.ma_méthode() | |||
42 | |||
ma_méthode() | |||
# erreur: NameError | |||
mon_instance = MaClasse() | |||
résultat = mon_instance.ma_méthode() | |||
print(résultat) | |||
# affiche: 42 | |||
Notez qu'on ne passe *pas* d'argument quand on apelle `ma_méthode` depuis l'instance. | |||
@@ -158,10 +160,10 @@ On peut le voir en utilisant des attributs:: | |||
print(self.x) | |||
>>> mon_instance = MaClasse() | |||
>>> mon_instance.x = 42 | |||
>>> mon_instance.affiche_attribut_x() | |||
42 | |||
mon_instance = MaClasse() | |||
mon_instance.x = 42 | |||
mon_instance.affiche_attribut_x() | |||
# Affiche: 42 | |||
On peut aussi *créer* des attributs dans une méthode:: | |||
@@ -171,13 +173,13 @@ On peut aussi *créer* des attributs dans une méthode:: | |||
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 = 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 | |||
mon_instance.crée_attribut_x() | |||
mon_instance.affiche_attribut_x() | |||
# affiche: 42 | |||
Les méthodes peuveunt aussi prendre plusieurs arguments, en plus de ``self`` - mais ``self`` doit | |||
toujours être le premier argument. | |||
@@ -192,10 +194,10 @@ Par example, pour créer un attribut avec une certaine valeur:: | |||
def affiche_attribut_x(self); | |||
print(self.x) | |||
>>> mon_instance = MaClasse() | |||
>>> mon_instance.crée_attribut_x(42) | |||
>>> mon_instance.affiche_attribut_x() | |||
42 | |||
mon_instance = MaClasse() | |||
mon_instance.crée_attribut_x(42) | |||
mon_instance.affiche_attribut_x() | |||
# affiche: 42 | |||
Méthodes appelant d'autres méthodes | |||
------------------------------------ | |||
@@ -217,8 +219,8 @@ les unes les autres:: | |||
print("fin de la méthode 2") | |||
>>> mon_instance = MaClasse() | |||
>>> mon_instance.méthode_2() | |||
mon_instance = MaClasse() | |||
mon_instance.méthode_2() | |||
.. code-block:: | |||
@@ -246,13 +248,13 @@ On utilise souvent ``__init__`` pour créer des attributs:: | |||
self.x = 1 | |||
self.y = 2 | |||
>>> mon_instance = MaClasse() | |||
mon_instance = MaClasse() | |||
# __init__ est appelée automatiquement! | |||
>>> mon_instance.x | |||
1 | |||
>>> mon_instance.y | |||
2 | |||
print(mon_instance.x) | |||
# affiche: 1 | |||
print(mon_instance.y) | |||
# affiche: 2 | |||
On prend souvent les *valeurs* des attributs à créer en arguments de la méthode ``__init__``:: | |||
@@ -264,11 +266,11 @@ On prend souvent les *valeurs* des attributs à créer en arguments de la métho | |||
Dans ce cas, les arguments de la méthode ``__init__`` apparaissent à l'intérieur des parenthèses après le | |||
nom de la classe:: | |||
>>> mon_instance = MaClasse(3, 4) | |||
>>> mon_instance.x | |||
3 | |||
>>> mon_instance.y | |||
4 | |||
mon_instance = MaClasse(3, 4) | |||
print(mon_instance.x) | |||
# affiche: 3 | |||
print(mon_instance.y) | |||
# affiche: 4 | |||
.. note:: | |||
@@ -16,27 +16,27 @@ Importer un module | |||
Ou: accéder à du code provenant d'un *autre* fichier source. | |||
Imaginons un fichier `bonjour.py` contenant seulement une assignation | |||
Créons un fichier `bonjour.py` contenant seulement une assignation | |||
d'une variable `a` à l'entier 42 :: | |||
# Dans bonjour.py | |||
a = 42 | |||
On peut accéder à cette variable en important le module, par | |||
exemple depuis l'interpréteur, en utilisant le mot-clé `import` | |||
suivi du nom du module:: | |||
Comme un fichier = un module, on vient de crée un module ``bonjour`` contenant une variable ``a``. | |||
$ python | |||
>>> import bonjour | |||
>>> bonjour.a | |||
42 | |||
Si maintenant on crée un fichier ``salutations.py`` dans le même répertoire, | |||
on peut accéder à cette variable en *important* le module:: | |||
Notez que pour que cela fonctionne: | |||
# Dans salutations.py | |||
import bonjour | |||
print(bonjour.a) | |||
# affiche: 42 | |||
* Le nom du module est écrit directement, ce n'est *pas* une | |||
.. note:: | |||
Le nom du module est écrit directement, ce n'est *pas* une | |||
chaîne de caractères. | |||
* Il faut lancer la commande `python` sans argument | |||
* Il faut la lancer depuis le répertoire qui contient `bonjour.py`. | |||
On voit que l'assignation de la variable `a` dans `bonjour.py` est devenue | |||
un *attribut* du module `bonjour` lorsque `bonjour` a été importé | |||
@@ -44,52 +44,26 @@ un *attribut* du module `bonjour` lorsque `bonjour` a été importé | |||
Si maintenant on rajoute une fonction ``dire_bonjour`` dans ``bonjour.py``:: | |||
# toujours dans bonjour.py | |||
# Dans bonjour.py | |||
a = 42 | |||
def dire_bonjour(): | |||
print("Bonjour!") | |||
On peut appeler la fonction ``dire_bonjour`` depuis l'interpréteur en accédant | |||
à l'attribut ``dire_bonjour`` du module ``bonjour``:: | |||
>>> import bonjour | |||
>>> bonjour.dire_bonjour() | |||
Bonjour! | |||
Différence avec la commande python | |||
----------------------------------- | |||
Notez bien que lancer l'interpréteur et taper `import bonjour` dedans n'est pas | |||
la même chose que lancer `python bonjour.py`. | |||
Dans le deuxième cas, tout le code dans `bonjour.py` est exécuté, puis la commande python | |||
se termine. | |||
Dans le cas de l'interpréteur, on peut utiliser tous les attributs du module et appeler | |||
les fonctions autant de fois qu'on veut:: | |||
>>> import bonjour | |||
>>> bonjour.dire_bonjour() | |||
Bonjour! | |||
>>> bonjour.dire_bonjour() | |||
Bonjour! | |||
On peut aussi modifier les valeurs des attributs:: | |||
>>> import bonjour | |||
>>> bonjour.a | |||
42 | |||
>>> bonjour.a = 36 | |||
>>> bonjour.a | |||
36 | |||
On peut appeler la fonction ``dire_bonjour`` depuis ``salutations.py`` | |||
en utilisant l'attribut ``dire_bonjour`` du module ``bonjour``:: | |||
# Dans salutations.py | |||
import bonjour | |||
bonjour.dire_bonjour() | |||
# affiche: Bonjour! | |||
Les imports ne sont faits qu'une seule fois | |||
------------------------------------------- | |||
Il est important de noter que le code à l'intérieur d'un | |||
module n'est *pas* ré-éxécuté si le module a déjà été | |||
importé auparavant. | |||
Il est important de noter que: | |||
* **tout** le code à l'intérieur d'un module est éxécuté lors du premier import | |||
* mais il n'est *pas* ré-éxécuté si le module a déjà été importé auparavant. | |||
On peut le voir en mettant du code dans `bonjour.py`, | |||
en plus des simples définitions de fonctions et assignations | |||
@@ -97,15 +71,20 @@ de variables:: | |||
# Dans bonjour.py | |||
print("Je suis le module bonjour et tu viens de m’importer") | |||
def dire_bonjour(): | |||
.... | |||
.. code-block:: python | |||
# Dans salutation.py | |||
import bonjour | |||
# affiche: Je suis le module bonjour et tu viens de m’importer | |||
>>> import bonjour | |||
Je suis le module foo et tu viens de m’importer | |||
>>> import bonjour | |||
<rien> | |||
import bojour | |||
# n'affiche rien | |||
Il faudra donc redémarrer l'interpréteur à chaque fois que le code dans `bonjour.py` change. | |||
a bibliothèque standard | |||
La bibliothèque standard | |||
------------------------ | |||
La bibliothèque standard est une collection de modules directement utilisables fournis à l'installation de Python. | |||
@@ -18,16 +18,17 @@ On peut utiliser pour cela deux classes: `Chat` et `Humain`:: | |||
def __init__(self, nom): | |||
self.nom = nom | |||
>>> chat = Chat("Monsieur Moustaches") | |||
>>> chat.nom | |||
'Monsieur Moustaches' | |||
chat = Chat("Monsieur Moustaches") | |||
prin(chat.nom) | |||
# affiche: Monsieur Moustaches | |||
class Humain: | |||
def __init__(self, prénom): | |||
self.prénom = prénom | |||
>>> alice = Humain(prénom="Alice") | |||
>>> alice.prénom | |||
"Alice" | |||
alice = Humain(prénom="Alice") | |||
print(alice.prénom) | |||
# affiche: Alice | |||
Maintenant on veut que les humains puissent adopter des chats. | |||
Pour cela, on peut rajouter la méthode ``adopte`` dans la classe | |||
@@ -43,10 +44,10 @@ classe ``Chat``:: | |||
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" | |||
boule_de_poils = Chat("Boule de Poils") | |||
alice = Humain("Alice") | |||
alice.adopte(boule_de_poils) | |||
# affiche: "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:: | |||
@@ -58,10 +59,10 @@ en utilisant la syntaxe ``nom.attribut`` vue précédemment:: | |||
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" | |||
boule_de_poils = Chat("Boule de Poils") | |||
alice = Humain("Alice") | |||
alice.adopte(boule_de_poils) | |||
# affiche: Alice adopte Boule de Poils | |||
Couplage | |||
-------- |
@@ -1,176 +0,0 @@ | |||
Rappels | |||
======= | |||
// TODO: drop? | |||
.. note:: | |||
ceci est surtout un rappel du chapitre 11. N'hésitez pas à vous y | |||
reporter si les exemples de code ne vous paraissent pas clairs. | |||
Classes vides | |||
------------- | |||
Définition:: | |||
class MaClasse: | |||
pass | |||
Instanciation:: | |||
instance_1 = MaClasse() | |||
Attributs | |||
--------- | |||
Un attribut est une variable *à l'intérieur* d'autre chose (par exemple une instance de classe). | |||
La syntaxe consiste en l'instance à gauche et l'attribut à droite après un point:: | |||
>>> 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:: | |||
class MaClasse: | |||
def ma_méthode(self): | |||
return 42 | |||
Les méthodes sont des attributs des instances de classes:: | |||
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.:: | |||
class MaClasse: | |||
def affiche_attribut_x(self): | |||
print(self.x) | |||
>>> mon_instance = MaClasse() | |||
>>> mon_instance.x = 42 | |||
>>> mon_instance.affiche_attribut_x() | |||
42 | |||
On peut aussi *créer* des attributs dans une méthode:: | |||
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 | |||
------------------------ | |||
.. code-block:: | |||
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 | |||
------------------------------------ | |||
.. code-block:: | |||
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") | |||
>>> mon_instance = MaClasse() | |||
>>> mon_instance.méthode_2() | |||
.. code-block:: | |||
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:: | |||
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:: | |||
class MaClasse: | |||
def __init__(self, x, y): | |||
self.x = x | |||
self.y = y | |||
>>> mon_instance = MaClasse(3, 4) | |||
>>> mon_instance.x | |||
3 | |||
>>> mon_instance.y | |||
4 |
@@ -10,20 +10,26 @@ Une classe à l'intérieur d'une autre classe. | |||
Dépendances entre fonctions | |||
----------------------------- | |||
Exemple: on veut dessiner un sapin dans le terminal:: | |||
Exemple :: | |||
def main(): | |||
largeur = demander_largeur() | |||
dessine_sapin(largeur) | |||
def calcule_x(): | |||
... | |||
# du code ici | |||
main() | |||
def fait_un_truc_avec_x(x): | |||
... | |||
# du code ici | |||
x = calcule_x() | |||
fait_un_truc_avec_x(x) | |||
On voit que la fonction ``dessine_sapin()`` prend un argument ``largeur``, qui est retourné | |||
par la fonction ``demander_largeur()``. | |||
``dessine_sapin()`` doit donc être appelée *après* ``demander_largeur()``. On dit que ``dessine_sapin()`` | |||
_dépend_ de ``demander_largeur()``. | |||
On voit que la fonction ``fait_un_truc_avec_x()`` prend un argument ``x``, qui est retourné | |||
par la fonction ``calcule_x()``. | |||
``fait_un_truc_avec_x()`` doit donc être appelée *après* ``calcule_x()``. On dit que ``fait_un_truc_avec_x()`` | |||
*dépend* de ``calcule_x()``. | |||
Dépendances entre classes | |||
------------------------- | |||
@@ -39,8 +45,8 @@ Revoyons la classe Chat:: | |||
Comme le constructeur de la classe Chat prend un nom en argument, il est impossible de construire | |||
des chats sans nom:: | |||
>>> chat = Chat() | |||
TypeError: __init__() missing 1 required positional argument: 'nom' | |||
chat = Chat() | |||
# erreur: TypeError: __init__() missing 1 required positional argument: 'nom' | |||
De la même façon, si on veut que tous les enfants aient un chat (pourquoi pas, après tout), on peut | |||
avoir une classe Enfant, dont le constructeur prend une instance de chat en plus du prénom:: | |||
@@ -50,11 +56,11 @@ avoir une classe Enfant, dont le constructeur prend une instance de chat en plus | |||
self.prénom = prénom | |||
self.chat = chat | |||
>>> alice = Enfant("Alice") | |||
TypeError: __init__() missing 1 required positional argument: 'chat' | |||
alice = Enfant("Alice") | |||
# erreur: TypeError: __init__() missing 1 required positional argument: 'chat' | |||
>>> boule_de_poils = Chat("Boule de Poils") | |||
>>> alice = Enfant("Alice", boule_de_poils) | |||
boule_de_poils = Chat("Boule de Poils") | |||
alice = Enfant("Alice", boule_de_poils) | |||
# OK! | |||
Utilisation de la composition | |||
@@ -78,9 +84,9 @@ et ``ronronne()`` dans la classe chat:: | |||
self.ronronne() | |||
>>> boule_de_poils = Chat("Boule de Poils") | |||
>>> boule_de_poils.caresse() | |||
Boule de Poils fait "prrrrr" | |||
boule_de_poils = Chat("Boule de Poils") | |||
boule_de_poils.caresse() | |||
# affiche: Boule de Poils fait "prrrrr" | |||
Ensuite, on peut rajouter la méthode ``console()`` dans la classe Enfant, | |||
qui va: | |||
@@ -95,11 +101,11 @@ qui va: | |||
def console(self): | |||
self.chat.caresse() | |||
>>> boule_de_poils = Chat("Boule de Poils") | |||
>>> alice = Enfant("Alice", boule_de_poils) | |||
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.console() | |||
# affiche: Boule de Poils fait "prrrrr" | |||
# Alice est consolée :) | |||
On dit parfois qu'on a *délégué* l'implémentation de la méthode ``console()`` de la classe Enfant |
@@ -4,6 +4,5 @@ Chapitre 13 - Classes (2ème partie) | |||
.. toctree:: | |||
:maxdepth: 1 | |||
01-rappels | |||
02-couplage | |||
03-composition | |||
01-couplage | |||
02-composition |
@@ -4,7 +4,7 @@ sys.path | |||
En Python, il existe une variable ``path`` prédéfinie dans le module ``sys`` qui fonctionne de manière similaire | |||
à la variable d'environnement ``PATH``. | |||
Si j'essaye de l'afficher sur ma machine, voici ce que j'obtiens: | |||
Si j'essaye de l'afficher sur ma machine, voici ce que j'obtiens:: | |||
import sys | |||
print(sys.path) | |||
@@ -147,6 +147,9 @@ On peut aussi interpréter des octets comme du texte - c'est la table ASCII | |||
.. image:: ../img/ascii-table.png | |||
La table se lit ainsi: si on veut connaître la suite de 0 et de 1 qui correspond à `B`: on lit | |||
les 3 premiers bits de haut en bas sur la colonne: `100`, puis les 4 bits sur la ligne: `0010`. | |||
Du coup 'B' en s'écrit en 7 bits: `1000010`, soit 66 en décimal, et 42 en héxadécimal | |||
ASCII - remarques | |||
----------------- | |||
@@ -155,20 +158,20 @@ ASCII - remarques | |||
* Le A est pour American | |||
* Ça sert à *envoyer* du texte sur des terminaux d'où les "caractères" non-imprimables dans la liste | |||
* Mais c'est une convention *très* utilisée | |||
* Techniquement, on n'a besoin que de 7 bits, mais on préfère envoyer des octets | |||
* Un message de 4 lettres ASCII sera souvent envoyé comme 4 octets (même si seulement 7 bits sont nécessaires) | |||
Utiliser ASCII en Python | |||
------------------------ | |||
Avec ``chr`` et ``ord``:: | |||
x = chr(98) | |||
x = chr(0x42) | |||
print(x) | |||
# affiche: b | |||
# affiche: B | |||
x = ord('a') | |||
x = ord('B') | |||
print(x) | |||
# affiche: 97 | |||
# affiche: 66 | |||
Affichage des bytearrays en Python | |||
---------------------------------- | |||
@@ -20,7 +20,7 @@ remarques. | |||
01-introduction/index | |||
02-premiers-pas/index | |||
03-variables-et-types/index | |||
04-code-source/index | |||
04-booléens/index | |||
05-flot-de-controle/index | |||
06-fonctions/index | |||
07-listes/index | |||