| @@ -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 | |||