{ "cells": [ { "cell_type": "markdown", "metadata": { "nbsphinx": "hidden" }, "source": [ "[prev: Noms et objets non immuables\n", "](naming-vs-pointer.ipynb) | [home](../index.ipynb) | [next: Listes en intention](list-comprehension.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Gérer les exceptions\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Qu'est-ce donc ?\n", "\n", "Une exception est levée quand une erreur est commise" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "NameError", "evalue": "name 'nexistepas' is not defined", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[1], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mnexistepas\u001b[49m\n", "\u001b[1;31mNameError\u001b[0m: name 'nexistepas' is not defined" ] } ], "source": [ "nexistepas" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "division by zero", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[2], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;241;43m2\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\n", "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero" ] } ], "source": [ "2 / 0" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "TypeError", "evalue": "can only concatenate str (not \"int\") to str", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[3], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mun\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\n", "\u001b[1;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" ] } ], "source": [ "'un' + 2" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "IndexError", "evalue": "string index out of range", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[4], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mbonjour\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m9\u001b[39;49m\u001b[43m]\u001b[49m\n", "\u001b[1;31mIndexError\u001b[0m: string index out of range" ] } ], "source": [ "'bonjour'[9]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "KeyError", "evalue": "'deux'", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[5], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43m{\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mun\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m}\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mdeux\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m\n", "\u001b[1;31mKeyError\u001b[0m: 'deux'" ] } ], "source": [ "{'un': 1}['deux']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Le *Traceback* permet de suivre l'imbrication des appels au moment de l'erreur" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "division by zero", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[6], line 13\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mf3\u001b[39m(x):\n\u001b[0;32m 11\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m f2(x) \u001b[38;5;241m/\u001b[39m \u001b[38;5;241m3\u001b[39m\n\u001b[1;32m---> 13\u001b[0m \u001b[43mf3\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\n", "Cell \u001b[1;32mIn[6], line 11\u001b[0m, in \u001b[0;36mf3\u001b[1;34m(x)\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mf3\u001b[39m(x):\n\u001b[1;32m---> 11\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mf2\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;241m/\u001b[39m \u001b[38;5;241m3\u001b[39m\n", "Cell \u001b[1;32mIn[6], line 8\u001b[0m, in \u001b[0;36mf2\u001b[1;34m(x)\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mf2\u001b[39m(x):\n\u001b[1;32m----> 8\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mf1\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;241m/\u001b[39m \u001b[38;5;241m2\u001b[39m\n", "Cell \u001b[1;32mIn[6], line 5\u001b[0m, in \u001b[0;36mf1\u001b[1;34m(x)\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mf1\u001b[39m(x):\n\u001b[1;32m----> 5\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mf0\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;241m/\u001b[39m \u001b[38;5;241m1\u001b[39m\n", "Cell \u001b[1;32mIn[6], line 2\u001b[0m, in \u001b[0;36mf0\u001b[1;34m(x)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mf0\u001b[39m(x):\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\n", "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero" ] } ], "source": [ "def f0(x):\n", " return x / 0\n", "\n", "def f1(x):\n", " return f0(x) / 1\n", "\n", "def f2(x):\n", " return f1(x) / 2\n", "\n", "def f3(x):\n", " return f2(x) / 3\n", "\n", "f3(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il est possible d'émettre soit même une exception pour signaler une erreur." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def fonction_qui_n_aime_pas_toto(valeur):\n", " \"\"\" affiche valeur\n", " Je n'aime pas Toto, donc 'toto' est une valeur interdite !\n", " \"\"\"\n", " if valeur == 'toto':\n", " raise ValueError(\"T'es pas beau, toto !\") # pensez à mettre un message utile...\n", " print(valeur)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tata\n" ] } ], "source": [ "fonction_qui_n_aime_pas_toto('tata')" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "ValueError", "evalue": "T'es pas beau, toto !", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[9], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mfonction_qui_n_aime_pas_toto\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mtoto\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n", "Cell \u001b[1;32mIn[7], line 6\u001b[0m, in \u001b[0;36mfonction_qui_n_aime_pas_toto\u001b[1;34m(valeur)\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\" affiche valeur\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;124;03mJe n'aime pas Toto, donc 'toto' est une valeur interdite !\u001b[39;00m\n\u001b[0;32m 4\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 5\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m valeur \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoto\u001b[39m\u001b[38;5;124m'\u001b[39m:\n\u001b[1;32m----> 6\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mT\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mes pas beau, toto !\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;66;03m# pensez à mettre un message utile...\u001b[39;00m\n\u001b[0;32m 7\u001b[0m \u001b[38;5;28mprint\u001b[39m(valeur)\n", "\u001b[1;31mValueError\u001b[0m: T'es pas beau, toto !" ] } ], "source": [ "fonction_qui_n_aime_pas_toto('toto')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## De nombreuses exceptions sont définies de base\n", "\n", "https://docs.python.org/2/library/exceptions.html#exception-hierarchy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## try / except / else /finally\n", "\n", "Il est possible de 'sécuriser' une portion de code. Voire même d'intégrer l'erreur dans la logique du code.\n", "\n", "``` python\n", "try:\n", " # bloc d'instruction dont on veux contrôler les exceptions émises\n", "except ExceptionType1 as err1:\n", " # Traitement de err1\n", " # Typiquement:\n", " # - on a une solution de repli dans le cas de err1\n", " # OU\n", " # - on sauve les meubles et on fait rebondir err1 (ou une nouvelle erreur)\n", "except ExceptionType2 as err2:\n", " # Traitement de err2\n", " # ...\n", "except ExceptionType3 as err3:\n", " # Traitement de err3\n", " # ...\n", "else:\n", " # Si aucune exception n'est émise dans le try\n", " # alors ce bloc est exécuté\n", "finally:\n", " # Ce bloc sera exécuté quoi qu'il arrive\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercices" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ecrire une fonction `get(obj, index, default)` avec le même comportement que `dict.get()` mais qui marche aussi bien pour les dict ou les listes .\n", "\n", "Ecrire une fonction `map_with_default(function, sequence, default)` qui marche comme `map(function, sequence)` sauf que si une erreur est produite par `function` lors de son évaluation, l'erreur n'est pas propagée. A la place, la valeur manquante est assignée à `default`." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" } }, "nbformat": 4, "nbformat_minor": 4 }