{ "cells": [ { "cell_type": "markdown", "id": "df36484a-b8d6-4e6b-9232-0ccc11b4d9a5", "metadata": {}, "source": [ "# Основы Python. Часть 2" ] }, { "cell_type": "markdown", "id": "c53ff008-8644-4b1e-84ad-3672830e0df4", "metadata": {}, "source": [ "## Перечислимые типы" ] }, { "cell_type": "markdown", "id": "8fa021bb-8177-4733-9935-1895a46b7535", "metadata": {}, "source": [ "### Базовые перечислимые типы\n", "\n", "| Тип | Название | Объявление | Порядок |\n", "| ----- | ----- | ----- | ----- |\n", "| `list` | Список | `[1, 2, 1]`, `[\"a\", \"b\", \"a\"]`, `[]` | Да |\n", "| `tuple` | Кортеж | `(1, 2, 1)`, `(\"a\", \"b\", \"a\")`, `(\"a\",)` | Да |\n", "| `set` | Набор | `{1, 3, 2}`, `{\"a\",\"c\",\"b\"}`, `set()` | Нет |\n", "| `dict` | Словарь | `{\"a\":1, \"c\":2, \"b\":1}`, `{}` | Сохраняет порядок вставки |\n", "\n", "Перечислимые типы являются изменяемыми. При присвоении переменные этих типов не копируются.\n", "\n", "Типы `tuple`, `str` и `bytes` имеют промежуточный статус. Они является неизменяемыми, но переменные этих типов можно перечислять.\n", "\n", "### Особенности перечислимых типов\n", "\n", "Элементы перечислимых типов могут быть произвольного, в том числе перечислимого типа:" ] }, { "cell_type": "code", "execution_count": 100, "id": "ab5254ea-5052-4e66-8da0-07a07c533cff", "metadata": {}, "outputs": [], "source": [ "data = [5,7,9,12,\"test\",True,[\"ab\",\"cd\",\"ef\"]]" ] }, { "cell_type": "markdown", "id": "90afeebf-c4a2-4cfb-94a8-9c34750a94e9", "metadata": {}, "source": [ "Списки и кортежи сохраняют порядок, а наборы и словари - нет:" ] }, { "cell_type": "code", "execution_count": 101, "id": "a8dbce96-0f92-43cc-a5d9-d71a23bf3f16", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5, 4, 3, 6, 2, 1]\n", "{1, 2, 3, 4, 5, 6}\n" ] } ], "source": [ "data_list = [5,4,3,6,2,1]\n", "data_set = {5,4,3,6,2,1}\n", "print(data_list)\n", "print(data_set)" ] }, { "cell_type": "markdown", "id": "deea9cd2-2684-48a6-8291-cf010724d4e0", "metadata": {}, "source": [ "Переменные перечислимых типов (как и все составных) при присвоении не копируются:" ] }, { "cell_type": "code", "execution_count": 102, "id": "eb765efb-1e85-4bcd-bafd-8c57b55bf0a8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5, 42, 9, 12]\n" ] } ], "source": [ "data = [5,7,9,12]\n", "double_data = data\n", "double_data[1] = 42\n", "print(data)" ] }, { "cell_type": "markdown", "id": "a273fbec-378f-4a0c-ad52-a5447780cfe2", "metadata": {}, "source": [ "Переменные перечислимых типов можно перечислять в цикле `for`." ] }, { "cell_type": "markdown", "id": "2a8b6b8e-625c-4d5c-97b6-95fb1433c8fc", "metadata": {}, "source": [ "## Цикл перебора элементов for\n", "\n", "Итерационные цикл for используется для обхода элементов последовательностей." ] }, { "cell_type": "markdown", "id": "0b30a1d9-175e-4011-981c-fbbb8516d32f", "metadata": {}, "source": [ "```\n", "for 〖переменные〗in 〖список или генератор〗:\n", " 〖операторы〗\n", "```" ] }, { "cell_type": "markdown", "id": "8a9e28d2-2ccc-4966-a86b-9338ed21e48a", "metadata": {}, "source": [ "Примеры:" ] }, { "cell_type": "code", "execution_count": 103, "id": "d0749117-7e5d-4f88-8629-877c63723552", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "п\n", "р\n", "и\n", "в\n", "е\n", "т\n" ] } ], "source": [ "x = \"привет\"\n", "for char in x:\n", " print(char)" ] }, { "cell_type": "code", "execution_count": 104, "id": "cc521242-db93-4e7a-9db9-cf581c75b2c0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "4\n", "5\n" ] } ], "source": [ "x = [3,4,5]\n", "for num in x:\n", " print(num)" ] }, { "cell_type": "markdown", "id": "7c61a248-9dc4-46ef-8875-362524c6dd7f", "metadata": {}, "source": [ "### Некоторые полезные генераторы" ] }, { "cell_type": "markdown", "id": "a9c667c0-9327-4484-a161-85819b498887", "metadata": {}, "source": [ "Элемент с индексом" ] }, { "cell_type": "code", "execution_count": 105, "id": "cd1f88c0-d34c-4cf4-b131-5a8da768a1b6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1\n", "1 2\n", "2 3\n" ] } ], "source": [ "for i, elem in enumerate([1,2,3]):\n", " print(i,elem)" ] }, { "cell_type": "markdown", "id": "447ff1c1-6988-4450-af35-2feb9aaefb33", "metadata": {}, "source": [ "Целые числа по порядку" ] }, { "cell_type": "code", "execution_count": 106, "id": "a0467a54-836e-41ba-af08-89ee7a07e3a5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n", "6\n", "7\n", "8\n", "9\n" ] } ], "source": [ "for i in range(5, 10, 1):\n", " print(i)" ] }, { "cell_type": "markdown", "id": "10894e8a-554b-4ac0-a4bd-7e93947baa5c", "metadata": {}, "source": [ "Синхронный обход списков" ] }, { "cell_type": "code", "execution_count": 107, "id": "f3134071-27c5-495d-8153-1f8dfa50515c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 a q\n", "2 b w\n", "3 c t\n" ] } ], "source": [ "for elem1, elem2, elem3 in zip([1,2,3], [\"a\",\"b\",\"c\"], \"qwt\"):\n", " print(elem1, elem2, elem3)" ] }, { "cell_type": "markdown", "id": "87368fcc-629b-45a0-9321-50b1ab4cd0ee", "metadata": {}, "source": [ "Полное декартово произведение" ] }, { "cell_type": "code", "execution_count": 108, "id": "100314f8-79a5-479d-b859-c4c972a8a582", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 a\n", "1 b\n", "1 c\n", "2 a\n", "2 b\n", "2 c\n", "3 a\n", "3 b\n", "3 c\n" ] } ], "source": [ "import itertools\n", "for elem1, elem2 in itertools.product([1,2,3], [\"a\",\"b\",\"c\"]):\n", " print(elem1, elem2)" ] }, { "cell_type": "markdown", "id": "9c0f5bc1-7b18-43c3-aed9-d4c223adfb32", "metadata": {}, "source": [ "### Список: list\n", "\n", "* Используется в качестве замены массивам и векторам\n", "* Может иметь произвольную длину\n", "* Его можно удлинять и укорачивать\n", "\n", "Индексирование в Python выполняется с 0." ] }, { "cell_type": "code", "execution_count": 109, "id": "9bd20abf-2cb0-4fbc-8ac5-6a16719bcc65", "metadata": {}, "outputs": [], "source": [ "data = ['a', 'b', 'c', 'd']\n", "data[0] # 'a'\n", "data[3] # 'd'\n", "# Отрицательные индексы нумеруют список с конца и с -1\n", "data[-1] # 'd'\n", "data[-4] # 'a'\n", "# Длина\n", "x = len(data) # x == 4\n", "# Поиск по значению\n", "x = data.index('c') # x == 2" ] }, { "cell_type": "raw", "id": "3cca8238-14a3-4ada-97c5-a7fddf015e79", "metadata": {}, "source": [ "data[4] # Ошибка: выход за пределы списка" ] }, { "cell_type": "markdown", "id": "ab929218-d908-453b-8698-91726ab4818c", "metadata": {}, "source": [ "### Срезы списков\n", "\n", "Срезы (slices) — это способ получать из списка его часть не прибегая к циклам.\n", "\n", "Синтаксис: `<индекс первого элемента>:<индекс последнего элемента +1>:<шаг>`" ] }, { "cell_type": "code", "execution_count": 110, "id": "266f7033-85e0-4267-852a-f78441c7c1f5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['b', 'c']\n", "['c', 'd']\n", "['a', 'b', 'c', 'd']\n", "['c', 'd']\n", "['b', 'd']\n" ] } ], "source": [ "data = ['a', 'b', 'c', 'd']\n", "print(data[1:3])\n", "print(data[2:])\n", "print(data[:])\n", "print(data[-2:])\n", "print(data[1:4:2])" ] }, { "cell_type": "markdown", "id": "aab1a763-e2fb-4420-851f-f49d104463fe", "metadata": {}, "source": [ "Срезы создают копию списка:" ] }, { "cell_type": "code", "execution_count": 111, "id": "1b36e1e0-8d4b-4c60-af58-006f3753ed26", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['a', 'b', 'c', 'd']\n", "['z', 'b', 'c', 'd']\n" ] } ], "source": [ "data = ['a', 'b', 'c', 'd']\n", "\n", "# есть копирование temp и data это разные списки\n", "temp = data[:]\n", "temp[0] = 'z'\n", "print(data)\n", "\n", "# нет копирования temp и data это один список с двумя именами\n", "temp = data\n", "temp[0] = 'z'\n", "print(data)" ] }, { "cell_type": "markdown", "id": "b05116f7-2b65-4955-b15c-8818f0d6a5c3", "metadata": {}, "source": [ "### Модификация списков" ] }, { "cell_type": "code", "execution_count": 112, "id": "5d693768-a704-41ce-8b23-b1a4e2e13cb6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[42, 'a', 'c', 'd', 42]\n", "[42, 'a', 'c', 'd', 42, 1, 2, 3]\n", "[42, 'a', 'c', 'd', 42, 1, 2] 3\n", "['a', 'c', 'd', 42, 1, 2] 42\n" ] } ], "source": [ "data = ['a', 'b', 'c', 'd']\n", "data[1] = 42\n", "del data[1]\n", "data.insert(0,42)\n", "data.append(42)\n", "print(data)\n", "\n", "data = data + [1,2,3]\n", "print(data)\n", "v = data.pop()\n", "print(data, v)\n", "v = data.pop(0)\n", "print(data, v)" ] }, { "cell_type": "markdown", "id": "2896f8b0-0026-4614-92e0-658de26bcdf5", "metadata": {}, "source": [ "### Перечисление элементов списков" ] }, { "cell_type": "code", "execution_count": 113, "id": "72bc7c5e-c378-4939-88e4-0aaa54b0dce6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n", "b\n", "c\n", "d\n", "0 a\n", "1 b\n", "2 c\n", "3 d\n" ] } ], "source": [ "data = ['a', 'b', 'c', 'd']\n", "for v in data:\n", " print(v)\n", "for i,v in enumerate(data):\n", " print(i,v)" ] }, { "cell_type": "markdown", "id": "666500ed-fde5-459c-8dc3-c66a6fc401ee", "metadata": {}, "source": [ "Если элемент списка неизменяемого типа, то при присвоение переменной созданной в цикле `for` (в примере, `v`) нового значение не меняет содержание массива." ] }, { "cell_type": "code", "execution_count": 114, "id": "aeecd0e9-8aef-4068-b99e-4706a95e5bd1", "metadata": {}, "outputs": [], "source": [ "i = 0\n", "while i < len(data):\n", " data[i] = 42\n", " i += 1\n", " \n", "for i in range(0,len(data)):\n", " data[i] = 42" ] }, { "cell_type": "markdown", "id": "08a082bf-3e50-4053-b14c-b1b96aa04bd4", "metadata": {}, "source": [ "### Сортировка списков" ] }, { "cell_type": "code", "execution_count": 115, "id": "a253d0d5-a10d-4f92-b371-e4eba8ec9797", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 4, 4, 5]\n", "[1, 2, 4, 4, 5]\n", "[5, 4, 4, 2, 1]\n", "[5, 4, 4, 2, 1]\n" ] } ], "source": [ "adata = [5,4,2,1,4]\n", "# Сортировка с копированием\n", "bdata = sorted(adata)\n", "print(bdata)\n", "# Сортировка на месте (in-place)\n", "adata.sort()\n", "print(adata)\n", "# Обратная сортировка\n", "bdata = sorted(adata, reverse=True)\n", "print(bdata)\n", "adata.sort(reverse=True)\n", "print(adata)" ] }, { "cell_type": "markdown", "id": "e01abf3f-1e23-4808-b9ef-e756bce27d5e", "metadata": {}, "source": [ "## Кортеж: tuple\n", "\n", "Кортеж это неизменяемый список. Часто встречается, как возвращаемое значение функций и генераторов." ] }, { "cell_type": "code", "execution_count": 116, "id": "47aa2057-127c-4566-b885-90590168a8ed", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "tple = (1, 2, 3)\n", "print(tple[0])" ] }, { "cell_type": "raw", "id": "5af4b703-04ad-4d77-acc7-bc64f8d5e45a", "metadata": {}, "source": [ "tple[0] = 0 # Ошибка\n", "tple.append(0) # Ошибка" ] }, { "cell_type": "markdown", "id": "1af81dfb-c114-4ce4-84e0-6300ce70b6c3", "metadata": {}, "source": [ "## Набор: set\n", "\n", "Набор не сохраняет порядок. Все элементы набора различны." ] }, { "cell_type": "code", "execution_count": 117, "id": "44630a68-4bed-455d-8340-10233e056e31", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{1, 2, 3, 4}\n", "{0, 1, 2, 3, 4}\n", "{0, 1, 2, 3, 4}\n", "{0, 1, 2, 3}\n" ] } ], "source": [ "vset = {4, 3, 2, 3, 1}\n", "print(vset)\n", "vset.add(0)\n", "print(vset)\n", "vset.add(4)\n", "print(vset)\n", "vset.remove(4)\n", "print(vset)" ] }, { "cell_type": "raw", "id": "22d42a8e-06cc-4360-863e-6b7cc4a87a6e", "metadata": {}, "source": [ "vset[0] # Ошибка" ] }, { "cell_type": "markdown", "id": "93fcf35b-056b-4229-9095-3cf4b12132fd", "metadata": {}, "source": [ "Типичное применение — хранение данных имеющих структуру множества и удаление дубликатов из списка: " ] }, { "cell_type": "code", "execution_count": 118, "id": "6fc25193-d6b6-4125-9fad-836038216537", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2]\n" ] } ], "source": [ "data = [1, 1, 2, 2, 2]\n", "data = list(set(data))\n", "print(data)" ] }, { "cell_type": "markdown", "id": "9a92f826-7c7b-4e96-bf64-0a00c594afa2", "metadata": {}, "source": [ "## Словарь: dict\n", "\n", "Набор пар ключ-значение. Ключи всегда различны.\n", "\n", "Значения могут быть любого типа, ключи — с некоторыми ограничениями." ] }, { "cell_type": "markdown", "id": "19d5d867-7f31-4aee-99de-59a591f3d73b", "metadata": {}, "source": [ "### Модификация словарей" ] }, { "cell_type": "code", "execution_count": 119, "id": "ead09e1d-540d-46c3-bf15-2ab275c704a1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'a': 1, 'b': 3, 'c': 3}\n", "{'a': 1, 'c': 3}\n", "{'a': 1, 'c': 3, 'f': 99}\n", "3\n", "{'a': 99, 'c': 3, 'f': 99, 'q': 64}\n" ] } ], "source": [ "data = {\"a\":1, \"b\":2, \"c\":3}\n", "data[\"b\"] = 3\n", "print(data)\n", "del data[\"b\"]\n", "print(data)\n", "data[\"f\"] = 99\n", "print(data)\n", "print(len(data))\n", "data.update({\"a\":99, \"q\":64})\n", "print(data)" ] }, { "cell_type": "markdown", "id": "6daaa0cf-534d-4697-b500-b7e72f12d6aa", "metadata": {}, "source": [ "### Перечисление элементов словарей" ] }, { "cell_type": "code", "execution_count": 120, "id": "3b565af7-0144-47d3-981f-d19ecda6bf7f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n", "1\n", "b\n", "2\n", "c\n", "3\n", "a 1\n", "b 2\n", "c 3\n" ] } ], "source": [ "data = {\"a\":1, \"b\":2, \"c\":3}\n", "\n", "for k in data:\n", " print(k)\n", " print(data[k]) \n", "\n", "for k in sorted(data.keys()):\n", " print(k,data[k])" ] }, { "cell_type": "markdown", "id": "eb147f58-77b0-47aa-940b-22f8fd043781", "metadata": {}, "source": [ "### Операторы над составными типами\n", "\n", "| Оператор | Действие | Пример |\n", "| -------- | -------- | ------ |\n", "| `in`, `not in` | Содержание, возвращает `bool` | `x in data` |\n", "| `y[x]` | Индексирование переменных перечислимых типов | `data[x]` |\n", "| `y.x` | Обращение к полю или методу объекта или модуля | `data.foo(2)` |" ] }, { "cell_type": "markdown", "id": "643f1140-9a3e-4b23-b6fd-84858937cf6f", "metadata": {}, "source": [ "### Приведение перечислимых типов\n", "\n", "| Исходный тип | Целевой тип | Приведение для переменных `data` и `keys` |\n", "| -------- | -------- | ------ |\n", "| `list` | `tuple` | `tuple(data)` |\n", "| `list` | `set` | `set(data)` |\n", "| `list` | `dict` | `dict(zip(keys,data))` |\n", "| `tuple` | `list` | `list(data)` |\n", "| `tuple` | `set` | `set(data)` |\n", "| `tuple` | `dict` | `dict(zip(keys,data))` |\n", "| `set` | `list` | `list(data)` |\n", "| `set` | `tuple` | `tuple(data)` |\n", "| `set` | `dict` | `dict(zip(keys,data))` |\n", "| `dict` | `list` | `list(data.keys())`, `list(data.values())` |\n", "| `dict` | `set` | `set(data.keys())`, `set(data.values())` |\n", "| `dict` | `tuple` | `tuple(data.keys())`, `tuple(data.values())` |" ] }, { "cell_type": "markdown", "id": "1ae164a9-a9dd-4ca2-a388-bd73cb6f01d0", "metadata": {}, "source": [ "## Объявление функций\n", "\n", "Как и в большинстве языков структурного программирования, блоки операторов можно оформлять в виде функций для дальнейшего использования." ] }, { "cell_type": "markdown", "id": "9ebea124-40be-44e2-9cb2-4a4105f22ac3", "metadata": {}, "source": [ "```\n", "def 〖имя функции〗(〖аргументы〗):\n", " 〖операторы〗\n", " return 〖возвращаемое значение〗\n", "```" ] }, { "cell_type": "markdown", "id": "378748a5-4ea6-425e-9cda-7e8c46911607", "metadata": {}, "source": [ "Функция может возвращать одно или несколько значений (в виде кортежа) или `None`.\n", "\n", "Объявление функции следует рассматривать, как присвоение значения соответствующей переменной." ] }, { "cell_type": "markdown", "id": "8ee102d0-1a6c-4a17-bfd6-318539e07002", "metadata": {}, "source": [ "### Модификация аргументов\n", "\n", "Базовые типы данных при вызове функций копируются, а составные нет." ] }, { "cell_type": "code", "execution_count": 121, "id": "68e2a2c9-a288-40e0-bc49-d9bf34063568", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6\n", "2\n" ] } ], "source": [ "def foo(x):\n", " x = x + 1\n", " return x\n", " \n", "w = foo(5)\n", "print(w)\n", "x = 1\n", "x = foo(x)\n", "print(x)" ] }, { "cell_type": "code", "execution_count": 122, "id": "2cfa9370-d8fb-40f2-a738-bf11f4c068e4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['42', 2, 3]\n" ] } ], "source": [ "def foo(x):\n", " x[0] = \"42\"\n", "\n", "w = [1, 2, 3]\n", "foo(w)\n", "print(w)" ] }, { "cell_type": "markdown", "id": "023d6388-b84d-4804-8213-1000cc872fc5", "metadata": {}, "source": [ "### Область видимости\n", "\n", "Функция видит переменные объявленные вне ее тела, но при попытке присвоения создает новые, локальные.\n", "\n", "Присвоение значений аргументам функции в ее теле равносильно созданию новых переменных." ] }, { "cell_type": "code", "execution_count": 123, "id": "2c0c9940-ab9f-4d33-9500-14700d8a6dac", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 3\n", "2 2\n" ] } ], "source": [ "y = 1\n", "\n", "def foo(x):\n", " y = x + 2\n", " return x,y\n", "\n", "a,b = foo(1)\n", "print(a,b)\n", "\n", "def foo(x):\n", " global y # Явно используем y из глобальной области\n", " x = x + y \n", " y = y + 1\n", " return x,y\n", "\n", "a,b = foo(1)\n", "print(a,b)" ] }, { "cell_type": "markdown", "id": "b6aee85f-c723-4d73-a169-9aef8964939a", "metadata": {}, "source": [ "### Аргументы по умолчанию\n", "\n", "При вызове функций можно пропускать аргументы, если для них задано значение по умолчанию" ] }, { "cell_type": "code", "execution_count": 124, "id": "43d527c7-acc9-48ac-8e53-791632a3c850", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "84\n" ] } ], "source": [ "def foo(x = 42):\n", " return x*2\n", " \n", "print(foo(1))\n", "print(foo())" ] }, { "cell_type": "markdown", "id": "69a5f51a-276a-457b-8425-2e8e3c194068", "metadata": {}, "source": [ "Обязательные аргументы всегда должны идти перед аргументами со значениями по умолчанию при объявлении функции." ] }, { "cell_type": "code", "execution_count": 125, "id": "354e09b6-6f21-4490-9ff6-f4d3680daee8", "metadata": {}, "outputs": [], "source": [ "def foo(x, y, z = 42): #Верно\n", " return x*y*2" ] }, { "cell_type": "raw", "id": "62e1521d-f0e4-4124-869d-8d80474cadb8", "metadata": {}, "source": [ "def foo(x = 42, y, z): #Ошибка\n", " return x*y*2" ] }, { "cell_type": "markdown", "id": "2d64fe27-b3e9-4cb3-a2c3-505a10cef235", "metadata": {}, "source": [ "### Порядок аргументов\n", "\n", "Обязательные аргументы должны передаваться по порядку.\n", "\n", "Аргументы со значениями по умолчанию можно передавать в произвольном порядке." ] }, { "cell_type": "code", "execution_count": 126, "id": "fbfff071-1caa-41c9-8cfd-ac493aa5ca95", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "49.0\n" ] } ], "source": [ "def foo(a, x = 1, y = 2, z = 3):\n", " return (x*y*z)/a\n", "\n", "print(foo(1, z = 7, y = 7))" ] }, { "cell_type": "markdown", "id": "b43aa162-fa2f-4db1-a404-e2cbda295c85", "metadata": {}, "source": [ "### Функция как аргумент" ] }, { "cell_type": "code", "execution_count": 127, "id": "cd887286-6652-4712-ae0d-ea204f48f808", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "11.0\n" ] } ], "source": [ "def foo(x):\n", " return x**2\n", "\n", "def bar(x):\n", " return x**3 / 3\n", "\n", "def calc(f, x, a):\n", " return f(x) + a\n", " \n", "print(calc(foo,1,2))\n", "print(calc(bar,3,2))" ] }, { "cell_type": "markdown", "id": "d3929aae-2b74-4b92-8a30-e7fc2dcb7322", "metadata": {}, "source": [ "### Что еще нужно знать о функциях\n", "\n", "* Функция — объект специального составного типа function\n", "* Объявление одной и той-же функции несколько раз не выдаст ошибки\n", "* Функции можно складывать в списки, словари, проверять на тождество\n", "* Функции можно объявлять внутри функций, кроме слова `global` есть слово `nonlocal`, которое делает тоже самое, но для локальных переменных\n", "* Функции с помощью специальных приемов могут обрабатывать произвольное число аргументов (подробнее)\n", "* Функции можно вызывать рекурсивно\n", "* Есть особые функции: лямбда (безымянные) и генераторы (запоминающие свое состояние)" ] }, { "cell_type": "markdown", "id": "2a89251d-722a-4b28-a034-4ebc8eac0cf9", "metadata": {}, "source": [ "## Исключения\n", "\n", "### Возникновение исключений\n", "\n", "Когда происходит ошибка — возбуждается соответствующее исключение. Обработка исключения — основой способ обработки ошибок в Python." ] }, { "cell_type": "raw", "id": "6d1ea214-6cde-4ab3-b6af-bdc74e4318f4", "metadata": {}, "source": [ "4/0 # Exception ZeroDivisionError" ] }, { "cell_type": "markdown", "id": "de36a160-e500-4b28-88ba-bde895184757", "metadata": {}, "source": [ "Когда происходит исключение Python начинает искать обработчик исключения для данного блока, при необходимости выходя из функций. Если обработчик не найден, то интерпретатор завершается (или выдает ошибку в интерактивном режиме)." ] }, { "cell_type": "markdown", "id": "cc3f1810-afd7-40d7-95b5-b4cad08430e2", "metadata": {}, "source": [ "### Обработка исключений" ] }, { "cell_type": "raw", "id": "ad564fb3-10a9-483a-9dfc-bbb2bc52ab1f", "metadata": {}, "source": [ "try:\n", " #блок кода в котором\n", " #ожидается возникновение исключения\n", "except ZeroDivisionError as e:\n", " #блок кода который будет выполнен\n", " #если возникнет исключение типа ZeroDivisionError\n", "else:\n", " #блок кода который будет выполнен\n", " #если исключение в блоке try не возникнет\n", "finally:\n", " #блок кода, который будет выполнен в любом случае" ] }, { "cell_type": "markdown", "id": "87831a0f-7aed-4b89-a949-5e7fda57453b", "metadata": {}, "source": [ "Можно перехватывать все типы исключения написав `except:`, но это маскирует ошибки." ] }, { "cell_type": "markdown", "id": "7d744266-92e6-4720-a4fa-25fe60f4ac28", "metadata": {}, "source": [ "### Популярные типы исключений\n", "\n", "| Исключение | Описание |\n", "| -------- | -------- |\n", "| `IndexError` | Индекс за пределами массива |\n", "| `KeyError` | Ключ отсутствует в словаре |\n", "| `NameError` | Обращение к необъявленной переменной (методу, классу) |\n", "| `UnboundLocalError` | Обращение к недоступной переменной |\n", "| `OSError` | Ошибки системы (права на файл, нет места на диске, …) |\n", "| `TypeError` | Операция не поддерживается данным типом данных (вычитание строк, …) |\n", "| `ValueError` | Недопустимое значение переменной (`float('hello')`, …) |\n", "| `NotImplementedError` | Метод не реализован |\n", "\n", "Исключение также можно выбросить прямо в коде. Для этого используется ключевое слово `raise`." ] }, { "cell_type": "raw", "id": "204968a9-98c2-48ee-bedf-ab534a3db659", "metadata": {}, "source": [ "raise Exception(\"Произошла ошибка\")" ] }, { "cell_type": "markdown", "id": "2feacfa3-0123-4ba6-99bd-f55b70f8e809", "metadata": {}, "source": [ "### Примеры использования" ] }, { "cell_type": "code", "execution_count": 128, "id": "f5d2aeb6-4524-447b-a8f0-95f58319540b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "123.15\n", "1231.5\n" ] } ], "source": [ "value_str = \"123.15\"\n", "value_float = 0.0\n", "\n", "try:\n", " value_float = float(value_str)\n", "except ValueError:\n", " print(\"Это не число!\")\n", "finally:\n", " print(value_float)\n", " \n", "print(value_float*10)" ] }, { "cell_type": "markdown", "id": "72e5664c-df8b-46a9-91f5-ec6ff8fe7d8e", "metadata": {}, "source": [ "### Примеры использования в функции" ] }, { "cell_type": "code", "execution_count": 129, "id": "9b5ac934-691a-47ee-9fe9-4a01675d9587", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Неправильный тип округления\n" ] } ], "source": [ "def fix(x, fix_type = None):\n", " if fix_type == \"round\":\n", " return round(x)\n", " elif fix_type == \"ceil\":\n", " return math.ceil(x)\n", " elif fix_type == \"trunc\":\n", " return math.trunc(x)\n", " else:\n", " raise ValueError(\"Недопустимое значение переменной fix_type\")\n", "\n", "#ft = input(\"Введите тип округления:\")\n", "ft = 'unknown'\n", "value = 73/13\n", "try:\n", " value = fix(value, ft)\n", "except ValueError:\n", " print(\"Неправильный тип округления\")\n", " value = fix(value, \"round\")" ] }, { "cell_type": "markdown", "id": "0a6824c3-726c-4edc-854c-1b5d886d387d", "metadata": {}, "source": [ "### Что еще нужно знать об исключениях\n", "\n", "* «Я не знаю, что дальше делать, я вызываю `raise`»\n", "* Оператор `try` почти ничего не стоит, но обработка возникшего исключения дело более ресурсоемкое (хотя и не очень), поэтому не следует использовать исключения вместо `if`\n", "* Объект исключения можно преобразовать в `str`, обычно это используется для вывод сообщений об ошибках\n", "* Исключение можно возбудить повторно, вызвав `raise` без аргументов в обработчике\n", "* Исключения можно содержательно анализировать с помощью методов модуля `traceback`" ] }, { "cell_type": "markdown", "id": "a7e16a66-b7c2-475f-b5f5-6d76ffb64726", "metadata": {}, "source": [ "## Модули" ] }, { "cell_type": "code", "execution_count": 130, "id": "e34506af-185f-474b-a949-eeb982749e24", "metadata": {}, "outputs": [], "source": [ "import os\n", "os.getcwd();" ] }, { "cell_type": "code", "execution_count": 131, "id": "94bdcc53-7f35-48a9-a73e-2ce6cfd571bd", "metadata": {}, "outputs": [], "source": [ "from os import getcwd\n", "getcwd();" ] }, { "cell_type": "markdown", "id": "06249a47-a664-4747-9819-8a0b6fbb5233", "metadata": {}, "source": [ "Порядок поиск при импорте:\n", "* Файлы в папке программы\n", "* Файлы в переменной окружения `$PYTHONPATH`\n", "* Сторонние пакеты\n", "* Стандартная библиотека" ] }, { "cell_type": "markdown", "id": "915d4b88-8373-4e36-9317-f00955cb6d86", "metadata": {}, "source": [ "### Собственные модули\n", "\n", "Файл `mylib.py`: " ] }, { "cell_type": "code", "execution_count": 132, "id": "54d37ea5-efe9-4e47-97cc-44625914d1fe", "metadata": {}, "outputs": [], "source": [ "def foo(x):\n", " return x*x\n", "\n", "class MyClass:\n", " def __init__(self):\n", " self.v = 0" ] }, { "cell_type": "markdown", "id": "30b9fb1a-60fc-40b8-848d-94d367f5c2b9", "metadata": {}, "source": [ "Файл `program.py`: " ] }, { "cell_type": "raw", "id": "dd6cf353-663f-43fb-9477-4f11afb6606c", "metadata": {}, "source": [ "import mylib\n", "print(mylib.foo(4))" ] }, { "cell_type": "raw", "id": "2018c518-6b1a-4b3b-aed6-fedd7f7f2bca", "metadata": {}, "source": [ "form mylib import MyClass,foo\n", "ob = MyClass()\n", "print(foo(4))" ] }, { "cell_type": "markdown", "id": "f7c24828-74c6-4412-b19c-24d147a9a714", "metadata": {}, "source": [ "### Разница между импортом и запуском" ] }, { "cell_type": "markdown", "id": "329a64fb-9338-4d1a-b4fd-a6e3053b2a31", "metadata": {}, "source": [ "Модуль может определить загружен ли он через `import` или запущен как программа." ] }, { "cell_type": "raw", "id": "7b43933c-f2bb-4184-993a-09cd7f952551", "metadata": {}, "source": [ "if __name__ == \"__main__\":\n", " main()" ] }, { "cell_type": "markdown", "id": "3e33ed5d-8208-4789-9176-9e525d12a744", "metadata": {}, "source": [ "Функция `main()` будет вызвана только если скрипт запущен как программа и не будет запускаться если он импортирован в другой скрипт." ] } ], "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.12.6" } }, "nbformat": 4, "nbformat_minor": 5 }