exceptions
This commit is contained in:
		
							parent
							
								
									5945030604
								
							
						
					
					
						commit
						732046428a
					
				
					 1 changed files with 498 additions and 0 deletions
				
			
		
							
								
								
									
										498
									
								
								11.exceptions.ipynb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								11.exceptions.ipynb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,498 @@ | ||||||
|  | { | ||||||
|  |  "cells": [ | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "c22bb274-b34a-415d-96a5-aabee2a87b59", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [ | ||||||
|  |     "# Exceptions in Python\n", | ||||||
|  |     "\n", | ||||||
|  |     "Most of the time we're concerned with the \"correct\" path through a program.\n", | ||||||
|  |     "Sometimes things can go wrong, and we need to take an \"exceptional\" path." | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 1, | ||||||
|  |    "id": "c69f70a0-f070-4d3c-adaa-a4520cd73af5", | ||||||
|  |    "metadata": { | ||||||
|  |     "tags": [] | ||||||
|  |    }, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "def my_func(a, b):\n", | ||||||
|  |     "    \"\"\" what can go wrong with this function? \"\"\"\n", | ||||||
|  |     "    if a > b:\n", | ||||||
|  |     "        return a / b\n", | ||||||
|  |     "    else:\n", | ||||||
|  |     "        return a * c" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 2, | ||||||
|  |    "id": "ade6c979-7fd0-460e-b6cf-be8cd800e230", | ||||||
|  |    "metadata": { | ||||||
|  |     "tags": [] | ||||||
|  |    }, | ||||||
|  |    "outputs": [ | ||||||
|  |     { | ||||||
|  |      "data": { | ||||||
|  |       "text/plain": [ | ||||||
|  |        "5.0" | ||||||
|  |       ] | ||||||
|  |      }, | ||||||
|  |      "execution_count": 2, | ||||||
|  |      "metadata": {}, | ||||||
|  |      "output_type": "execute_result" | ||||||
|  |     } | ||||||
|  |    ], | ||||||
|  |    "source": [ | ||||||
|  |     "my_func(10, 2)" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 3, | ||||||
|  |    "id": "1ef88eb5-0852-4d97-bd25-340b83730442", | ||||||
|  |    "metadata": { | ||||||
|  |     "tags": [] | ||||||
|  |    }, | ||||||
|  |    "outputs": [ | ||||||
|  |     { | ||||||
|  |      "ename": "ZeroDivisionError", | ||||||
|  |      "evalue": "division by zero", | ||||||
|  |      "output_type": "error", | ||||||
|  |      "traceback": [ | ||||||
|  |       "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | ||||||
|  |       "\u001b[0;31mZeroDivisionError\u001b[0m                         Traceback (most recent call last)", | ||||||
|  |       "Cell \u001b[0;32mIn[3], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmy_func\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n", | ||||||
|  |       "Cell \u001b[0;32mIn[1], line 4\u001b[0m, in \u001b[0;36mmy_func\u001b[0;34m(a, b)\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\" what can go wrong with this function? \"\"\"\u001b[39;00m\n\u001b[1;32m      3\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m a \u001b[38;5;241m>\u001b[39m b:\n\u001b[0;32m----> 4\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\n\u001b[1;32m      5\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m      6\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m a \u001b[38;5;241m*\u001b[39m c\n", | ||||||
|  |       "\u001b[0;31mZeroDivisionError\u001b[0m: division by zero" | ||||||
|  |      ] | ||||||
|  |     } | ||||||
|  |    ], | ||||||
|  |    "source": [ | ||||||
|  |     "my_func(10, 0)" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 4, | ||||||
|  |    "id": "776c8d17-0c17-49a6-9a1d-ef5fbaf7859b", | ||||||
|  |    "metadata": { | ||||||
|  |     "tags": [] | ||||||
|  |    }, | ||||||
|  |    "outputs": [ | ||||||
|  |     { | ||||||
|  |      "ename": "NameError", | ||||||
|  |      "evalue": "name 'c' is not defined", | ||||||
|  |      "output_type": "error", | ||||||
|  |      "traceback": [ | ||||||
|  |       "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | ||||||
|  |       "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)", | ||||||
|  |       "Cell \u001b[0;32mIn[4], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmy_func\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m)\u001b[49m\n", | ||||||
|  |       "Cell \u001b[0;32mIn[1], line 6\u001b[0m, in \u001b[0;36mmy_func\u001b[0;34m(a, b)\u001b[0m\n\u001b[1;32m      4\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m a \u001b[38;5;241m/\u001b[39m b\n\u001b[1;32m      5\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m----> 6\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m a \u001b[38;5;241m*\u001b[39m \u001b[43mc\u001b[49m\n", | ||||||
|  |       "\u001b[0;31mNameError\u001b[0m: name 'c' is not defined" | ||||||
|  |      ] | ||||||
|  |     } | ||||||
|  |    ], | ||||||
|  |    "source": [ | ||||||
|  |     "my_func(2, 10)" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "b7a97b68-43a1-4c10-8621-284d434b12a9", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 7, | ||||||
|  |    "id": "1191e7d1-4037-47d7-a899-4f0c0d6846ff", | ||||||
|  |    "metadata": { | ||||||
|  |     "tags": [] | ||||||
|  |    }, | ||||||
|  |    "outputs": [ | ||||||
|  |     { | ||||||
|  |      "ename": "TypeError", | ||||||
|  |      "evalue": "'>' not supported between instances of 'int' and 'str'", | ||||||
|  |      "output_type": "error", | ||||||
|  |      "traceback": [ | ||||||
|  |       "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | ||||||
|  |       "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)", | ||||||
|  |       "Cell \u001b[0;32mIn[7], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmy_func\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m1\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n", | ||||||
|  |       "Cell \u001b[0;32mIn[1], line 2\u001b[0m, in \u001b[0;36mmy_func\u001b[0;34m(a, b)\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mmy_func\u001b[39m(a, b):\n\u001b[0;32m----> 2\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m>\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m:\n\u001b[1;32m      3\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m a \u001b[38;5;241m/\u001b[39m b\n\u001b[1;32m      4\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m:\n", | ||||||
|  |       "\u001b[0;31mTypeError\u001b[0m: '>' not supported between instances of 'int' and 'str'" | ||||||
|  |      ] | ||||||
|  |     } | ||||||
|  |    ], | ||||||
|  |    "source": [ | ||||||
|  |     "my_func(10, \"1\")" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 8, | ||||||
|  |    "id": "9b301d27-ce89-424f-bf21-cd42f7ef724e", | ||||||
|  |    "metadata": { | ||||||
|  |     "tags": [] | ||||||
|  |    }, | ||||||
|  |    "outputs": [ | ||||||
|  |     { | ||||||
|  |      "ename": "TypeError", | ||||||
|  |      "evalue": "unsupported operand type(s) for /: 'str' and 'str'", | ||||||
|  |      "output_type": "error", | ||||||
|  |      "traceback": [ | ||||||
|  |       "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | ||||||
|  |       "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)", | ||||||
|  |       "Cell \u001b[0;32mIn[8], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmy_func\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mb\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43ma\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n", | ||||||
|  |       "Cell \u001b[0;32mIn[1], line 3\u001b[0m, in \u001b[0;36mmy_func\u001b[0;34m(a, b)\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mmy_func\u001b[39m(a, b):\n\u001b[1;32m      2\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m a \u001b[38;5;241m>\u001b[39m b:\n\u001b[0;32m----> 3\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\n\u001b[1;32m      4\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m      5\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m a \u001b[38;5;241m*\u001b[39m c\n", | ||||||
|  |       "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for /: 'str' and 'str'" | ||||||
|  |      ] | ||||||
|  |     } | ||||||
|  |    ], | ||||||
|  |    "source": [ | ||||||
|  |     "my_func(\"b\", \"a\")" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "6c8c321f-0a0f-4116-94e0-cb91421c1492", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [ | ||||||
|  |     "We could try to think of all possible conditions, and our simple function would become much longer & harder to read. \n", | ||||||
|  |     "\n", | ||||||
|  |     "Often there is no better solution than to have an error occur, so Python **raises an exception** and that is what happens here." | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "0877c7a7-a636-47a1-a5d2-05ff8e5bb920", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [ | ||||||
|  |     "The above types are called rumtime exceptions, because we don't see them until the code runs.\n", | ||||||
|  |     "\n", | ||||||
|  |     "This is different from a `SyntaxError` which means that Python can't parse our statements:\n", | ||||||
|  |     "\n", | ||||||
|  |     "```\n", | ||||||
|  |     "# Syntax Errors\n", | ||||||
|  |     "def my_func(a, b,: # missing )\n", | ||||||
|  |     "    if a > b\n", | ||||||
|  |     "      return a / b  # missing colon\n", | ||||||
|  |     "    else { return a * c }      # python doesn't use braces\n", | ||||||
|  |     "```" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "14c7426d-9b73-4712-b204-db9cd6bcde67", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [ | ||||||
|  |     "## Built-in Exceptions\n", | ||||||
|  |     "\n", | ||||||
|  |     "* `Exception` (base type)\n", | ||||||
|  |     "  * `ValueError`\n", | ||||||
|  |     "  * `TypeError`\n", | ||||||
|  |     "  * `KeyError`\n", | ||||||
|  |     "  * `IndexError`\n", | ||||||
|  |     "  * `NotImplementedError`\n", | ||||||
|  |     "  * `OSError`\n", | ||||||
|  |     "      * `FileNotFoundError`\n", | ||||||
|  |     "\n", | ||||||
|  |     "And many more: https://docs.python.org/3/library/exceptions.html#exception-hierarchy\n", | ||||||
|  |     "\n", | ||||||
|  |     "Note that exceptions form a hierarchy, we'll discuss this in more detail when we come to inheritance.\n", | ||||||
|  |     "\n", | ||||||
|  |     "## Handling Exceptions\n", | ||||||
|  |     "\n", | ||||||
|  |     "In practice, exceptions are **raised**, and either **caught** or not.  An uncaught exception stops the program and prints an error message to the screen as you've seen.\n", | ||||||
|  |     "\n", | ||||||
|  |     "We handle exceptions with `try-except` blocks." | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 14, | ||||||
|  |    "id": "5022b7c8-a19f-45cb-9d40-58abc48de961", | ||||||
|  |    "metadata": { | ||||||
|  |     "tags": [] | ||||||
|  |    }, | ||||||
|  |    "outputs": [ | ||||||
|  |     { | ||||||
|  |      "name": "stdout", | ||||||
|  |      "output_type": "stream", | ||||||
|  |      "text": [ | ||||||
|  |       "can't divide by zero, set c = 0\n" | ||||||
|  |      ] | ||||||
|  |     } | ||||||
|  |    ], | ||||||
|  |    "source": [ | ||||||
|  |     "try:\n", | ||||||
|  |     "    a = 3\n", | ||||||
|  |     "    b = 0\n", | ||||||
|  |     "    c = a / b\n", | ||||||
|  |     "except ZeroDivisionError:\n", | ||||||
|  |     "    c = 0\n", | ||||||
|  |     "    print(f\"can't divide by zero, set c = {c}\")" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "c996bd03-f79b-49de-874d-cd6cb076a70a", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [ | ||||||
|  |     "If an exception occurs within a `try` block, execution will jump to the appropriate `except` block if one exists.\n", | ||||||
|  |     "\n", | ||||||
|  |     "Typically you want to handle different errors differently, you can also handle multiple errors with one block by using any of the following:\n", | ||||||
|  |     "\n", | ||||||
|  |     "```python\n", | ||||||
|  |     "# multiple except blocks for different behaviors\n", | ||||||
|  |     "try:\n", | ||||||
|  |     "    something():\n", | ||||||
|  |     "except ValueError:\n", | ||||||
|  |     "    ...\n", | ||||||
|  |     "except IndexError:\n", | ||||||
|  |     "    ...\n", | ||||||
|  |     "```\n", | ||||||
|  |     "\n", | ||||||
|  |     "```python\n", | ||||||
|  |     "# one block w/ multiple types in a tuple\n", | ||||||
|  |     "try:\n", | ||||||
|  |     "    something()\n", | ||||||
|  |     "except (ValueError, IndexError, KeyError):  # tuple of return values\n", | ||||||
|  |     "    ...\n", | ||||||
|  |     "```\n", | ||||||
|  |     "\n", | ||||||
|  |     "```python\n", | ||||||
|  |     "# base exception type, use sparingly\n", | ||||||
|  |     "try:\n", | ||||||
|  |     "    something()\n", | ||||||
|  |     "except Exception:   # catches all runtime exceptions\n", | ||||||
|  |     "    ...\n", | ||||||
|  |     "except ArithmeticError:   # catches all errors derived from ArithmeticError\n", | ||||||
|  |     "```\n", | ||||||
|  |     "\n", | ||||||
|  |     "\n", | ||||||
|  |     "```python\n", | ||||||
|  |     "# DO NOT USE: bare except\n", | ||||||
|  |     "try:\n", | ||||||
|  |     "    something();\n", | ||||||
|  |     "except: \n", | ||||||
|  |     "    ...\n", | ||||||
|  |     "```\n", | ||||||
|  |     "\n", | ||||||
|  |     "```python\n", | ||||||
|  |     "try:\n", | ||||||
|  |     "    something()\n", | ||||||
|  |     "except OSError:   # will catch all subclasses of OSError\n", | ||||||
|  |     "    ...\n", | ||||||
|  |     "```" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "34060dea-77e4-420d-9895-5d866635f620", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [ | ||||||
|  |     "## Raising Exceptions\n", | ||||||
|  |     "\n", | ||||||
|  |     "To raise an exception, you use the `raise` keyword, which similarly to `return` exits a function immediately.\n", | ||||||
|  |     "\n" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 12, | ||||||
|  |    "id": "fd6d0e12-eae2-466e-8536-db5d246091f0", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "def f(positive):\n", | ||||||
|  |     "    if positive < 0:\n", | ||||||
|  |     "        raise ValueError(\"f requires a positive argument\")\n", | ||||||
|  |     "    return positive * positive" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 10, | ||||||
|  |    "id": "58c691a9-14ed-4fe1-9b0d-eb9b52a4d44d", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [ | ||||||
|  |     { | ||||||
|  |      "data": { | ||||||
|  |       "text/plain": [ | ||||||
|  |        "9" | ||||||
|  |       ] | ||||||
|  |      }, | ||||||
|  |      "execution_count": 10, | ||||||
|  |      "metadata": {}, | ||||||
|  |      "output_type": "execute_result" | ||||||
|  |     } | ||||||
|  |    ], | ||||||
|  |    "source": [ | ||||||
|  |     "f(3)" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 11, | ||||||
|  |    "id": "5fd8e7ee-53c6-4cd1-8748-cd66f06da9ac", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [ | ||||||
|  |     { | ||||||
|  |      "ename": "ValueError", | ||||||
|  |      "evalue": "f requires a positive argument", | ||||||
|  |      "output_type": "error", | ||||||
|  |      "traceback": [ | ||||||
|  |       "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | ||||||
|  |       "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)", | ||||||
|  |       "Cell \u001b[0;32mIn[11], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mf\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\n", | ||||||
|  |       "Cell \u001b[0;32mIn[9], line 3\u001b[0m, in \u001b[0;36mf\u001b[0;34m(positive)\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mf\u001b[39m(positive):\n\u001b[1;32m      2\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m positive \u001b[38;5;241m<\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m----> 3\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;124mf requires a positive argument\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m      4\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m positive \u001b[38;5;241m*\u001b[39m positive\n", | ||||||
|  |       "\u001b[0;31mValueError\u001b[0m: f requires a positive argument" | ||||||
|  |      ] | ||||||
|  |     } | ||||||
|  |    ], | ||||||
|  |    "source": [ | ||||||
|  |     "f(-1)" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "f86298c9-b7b4-4f9c-81c5-ad16df15b233", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [ | ||||||
|  |     "### Defining Custom Exception Types\n", | ||||||
|  |     "\n", | ||||||
|  |     "Sometimes you can use an existing type, but in practice it is very common to want to define custom exception types.\n", | ||||||
|  |     "\n", | ||||||
|  |     "Custom exception types let you handle your programs errors differently from Python's built in types:" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 14, | ||||||
|  |    "id": "af5d3624-3f4f-4f1d-9292-388f909a3bfd", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "class InvalidColor(Exception):\n", | ||||||
|  |     "    \"\"\" This exception is raised when an invalid color is passed. \"\"\"\n", | ||||||
|  |     "\n", | ||||||
|  |     "VALID_COLORS = (...)\n", | ||||||
|  |     "\n", | ||||||
|  |     "def draw_point(x, y, color):\n", | ||||||
|  |     "    if color not in VALID_COLORS:\n", | ||||||
|  |     "        raise InvalidColor(\"color should be one of the valid colors\")" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "5b82f7b0-49bd-4781-a2af-3d55a7ec0ae6", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [ | ||||||
|  |     "Exception classes must inherit from `Exception` or another exception.\n", | ||||||
|  |     "\n", | ||||||
|  |     "We'll talk more about inheritance next, but for now, just know that you need the `(Exception)` portion of the class declaration line." | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "d93053ab-4cd7-4751-bc81-3f6d13a7d908", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [ | ||||||
|  |     "## try-except-finally-else\n", | ||||||
|  |     "\n", | ||||||
|  |     "The full syntax for `try-except` includes two more optional clauses `finally` and `else`.\n", | ||||||
|  |     "\n", | ||||||
|  |     "These work somewhat like `elif`/`else`:\n", | ||||||
|  |     "\n", | ||||||
|  |     "```python\n", | ||||||
|  |     "try:\n", | ||||||
|  |     "    something()\n", | ||||||
|  |     "except Exception as e:   # \"as e\" allows using the exception if needed\n", | ||||||
|  |     "    ...   # executes only if exception was raised\n", | ||||||
|  |     "else:\n", | ||||||
|  |     "    ...   # executes if no exception raised\n", | ||||||
|  |     "finally:\n", | ||||||
|  |     "    ...   # executes after try/except/else no matter what\n", | ||||||
|  |     "```\n", | ||||||
|  |     "\n" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": 18, | ||||||
|  |    "id": "320d3309-099a-4f2e-9096-983101bfc157", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [ | ||||||
|  |     { | ||||||
|  |      "name": "stdout", | ||||||
|  |      "output_type": "stream", | ||||||
|  |      "text": [ | ||||||
|  |       "got a value error error message\n", | ||||||
|  |       "always prints at the end\n" | ||||||
|  |      ] | ||||||
|  |     } | ||||||
|  |    ], | ||||||
|  |    "source": [ | ||||||
|  |     "try:\n", | ||||||
|  |     "    #pass\n", | ||||||
|  |     "    raise ValueError(\"error message\")\n", | ||||||
|  |     "except ValueError as e:\n", | ||||||
|  |     "    print(\"got a value error\", e)\n", | ||||||
|  |     "else:\n", | ||||||
|  |     "    print(\"no exception raised\")\n", | ||||||
|  |     "finally:\n", | ||||||
|  |     "    print(\"always prints at the end\")" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "markdown", | ||||||
|  |    "id": "0ed69652-c95d-4745-8aa2-ac2171d06ad5", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "source": [ | ||||||
|  |     "## Best Practices\n", | ||||||
|  |     "\n", | ||||||
|  |     "Catch the narrowest exception that you need to, so that you don't accidentally \"handle\" exceptions that you don't intend to.\n", | ||||||
|  |     "\n", | ||||||
|  |     "Throw the most specific exception that you can, so that it can be handled by unique code if needed.\n", | ||||||
|  |     "\n", | ||||||
|  |     "Provide useful error messages as the argument to your exception. All exception types by default take a string that'll be used as a message:\n", | ||||||
|  |     "\n", | ||||||
|  |     "`raise ValueError(\"say why the value was rejected\")`" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "id": "2d6c25cf-cd55-4d33-99f3-7b0d5f7eab86", | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [] | ||||||
|  |   } | ||||||
|  |  ], | ||||||
|  |  "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.15" | ||||||
|  |   } | ||||||
|  |  }, | ||||||
|  |  "nbformat": 4, | ||||||
|  |  "nbformat_minor": 5 | ||||||
|  | } | ||||||
		Loading…
	
		Reference in a new issue