Главная / Курсы / Python / Глава 1. Ключевые факты
# Глава 1. Ключевые факты > Прост, как свинья, а лукав, как змея. Народная пословица Глава посвящается ключевым фактам о питоне. Их хватит, чтобы сложить о языке первое представление, узнать его яркие особенности и изящно поддержать светскую беседу. ## Что такое питон Питон — это интерпретируемый язык. Поддерживает объектно-ориентированную и функциональную парадигмы программирования. **Управление памятью** в питоне реализуется через подсчет ссылок и сборщик мусора. Типизация в питоне неявная, динамическая, строгая. Что это значит? **Неявная типизация.** При объявлении переменной не нужно указывать ее тип: ```python code_ok = 200 response_ok = "OK" ``` Объявите переменную `err_service_unavailable`, равную 503. {.task_text} ```python {.task_source #python_chapter_0010_task_0010} ``` Синтаксис: переменная = значение {.task_hint} ```python {.task_answer} err_service_unavailable = 503 ``` **Динамическая типизация.** По мере выполнения кода одна и та же переменная может содержать значения разных типов, от строки до числа или флага. {#block-dynamic-typing} ```python res = True res = "Success" res = -1 ``` А все потому, что абсолютно любая переменная в питоне — всего лишь имя для ссылки на объект в памяти. В любой момент времени ссылку можно переназначить. Ошибки типов (вроде обращения к несуществующему полю объекта) выявляются в рантайме. Допустим, мы хотим взять элемент по индексу 2 у числа. Как будто это не число, а массив: ```python x = 10 print(x[2]) ``` Скрипт запустится, но завершится с ошибкой: ``` TypeError: 'int' object is not subscriptable ``` **Строгая типизация.** Казалось бы, какая тут строгость, если одной и той же переменной без проблем присваиваются значения разных типов. Речь о том, что в питоне нет неявного приведения типов. И этим он отличается от языков со слабой типизацией — JavaScript, PHP и других. Если попытаться сложить строку и число, то скрипт упадет с ошибкой интерпретатора о несовпадении типов: ```python print("Returned HTTP code " + 200) ``` ``` TypeError: must be str, not int ``` Исправьте этот пример, явно приведя число к строке встроенной функцией `str()`. {.task_text} ```python {.task_source #python_chapter_0010_task_0020} print("Returned HTTP code " + 200) ``` В функцию `print()` необходимо передать две строки, сложенных с помощью оператора `+`. Первая строка: `"Returned HTTP code "`. Вторая строка: число 200, конвертированное в строку с помощью функции `str()`. Функция `str()` принимает аргумент и возвращает строку, к которой приведен аргумент. {.task_hint} ```python {.task_answer} print("Returned HTTP code " + str(200)) ``` ## Любимые грабли начинающих питонистов Как, не зная синтаксис, догадаться, что исходник написан на питоне? Все просто: для обозначения вложенных блоков кода питон использует пробелы либо табы. Вместо фигурных скобочек как в Go, JavaScript и других популярных языках в питоне верхнеуровневое выражение заканчивается **двоеточием,** а дальше в коде появляется отступ. Сравните скверно отформатированный, но рабочий код на C++: ```c++ while (true) { bool ok = match_query(query); if (ok) break; } ``` ...с тем же кодом, но на питоне: ```python while True: ok = match_query(query) if ok: break ``` Да, отступы — это неотъемлемая часть синтаксиса питона. Это не пожелание кодстайла для упрощения восприятия кода. Если забыть расставить отступы, интерпретатор завершит выполнение скрипта ошибкой: ``` IndentationError: expected an indented block ``` В качестве отступов можно использовать как пробелы, так и табы. Главное — выбрать что-то одно и не смешивать, иначе получите уже другую ошибку: ``` TabError: inconsistent use of tabs and spaces in indentation ``` Исправьте ошибки в коде. {.task_text} ```python {.task_source #python_chapter_0010_task_0030} new_items = [2, 8, 6] for item in new_items print(item) ``` Функция `print()` должна вызываться внутри цикла с новой строки. Перед ней нужно поставить отступ (например, 4 пробела). После цикла должно стоять двоеточие. {.task_hint} ```python {.task_answer} new_items = [2, 8, 6] for item in new_items: print(item) ``` Отсутствие отступов и смешивание табов с пробелами — **лидеры рейтинга ошибок** начинающих питонистов. Чтобы на этом не попадаться, нужна практика. В этом коде допущено несколько ошибок. Почините код, исправив синтаксические ошибки. {.task_text} Что вообще в этом скрипте происходит? На первой строчке создается `matrix` — [список](/courses/python/chapters/python_chapter_0110/) элементов. Внутри цикла `for` объект `matrix` заполняется элементами - списками (то есть становится списком списков — матрицей 5x5). Элементы внутри вложенных списков заполняются целочисленными значениями. {.task_text} ```python {.task_source #python_chapter_0010_task_0040} matrix = list() for i in range(0, 5) matrix.append(list()) for j in range(0, 5) matrix[i].append(i * j) print(matrix) ``` В объявлениях циклов пропущены двоеточия. {.task_hint} ```python {.task_answer} for i in range(0, 5): matrix.append(list()) for j in range(0, 5): matrix[i].append(i * j) print(matrix) ``` ## Сильные и слабые стороны За что питон любят: + **Простота.** Питон быстро учится, код на нем легко читается. + **Лаконичность.** За счет своей высокоуровневости питон не такой многословный как C++ или Java. + **Богатство библиотек** — стандартных и опенсорсных. Модули для веба, GUI, data science, машинного обучения и всего на свете. + **Высокая скорость разработки** как следствие перечисленных пунктов. Поэтому питон столь любим бизнесом. + **Интроспекция и рефлексия.** [Интроспекция](https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D1%80%D0%BE%D1%81%D0%BF%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)) — возможность в рантайме для любого объекта выяснить его тип, список методов и полей, родительские классы и прочие ценные свойства. [Рефлексия](https://ru.wikipedia.org/wiki/%D0%9E%D1%82%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)) — возможность исполняемого кода не только получать, но и модифицировать собственную структуру и поведение. + **Интерактивный режим** запуска интерпретатора, полезный для быстрой проверки небольших фрагментов кода, валидации идей, изучения языка. За что питон ругают: - **Низкое быстродействие.** Следствие интерпретируемости и высокоуровневости. Исполнение кода обеспечивает виртуальная машина, и при каждом запуске скрипта интерпретатор парсит код и строит AST-дерево. Эту проблему можно сгладить: сохранять промежуточный байт-код в специальных файлах, чтобы не генерировать его заново при каждом перезапуске. - **GIL** (global interpreter lock). Интерпретатор питона устроен так, что он запрещает выполнять несколько потоков одновременно. Процессы — пожалуйста. Потоки — нет. Это не шутка. Истинной параллельности потоков в питоне нет, потому что при выполнении кода интерпретатор оперирует потоко-небезопасными переменными. Чтобы гарантировать сохранность этих переменных, каждый поток интерпретатора вынужден захватывать и отпускать [GIL.](/courses/python/chapters/python_chapter_0290/) - **Зависимость от системных библиотек.** При установке питон-приложения на целевую машину придется разбираться с настройкой виртуального окружения, изолирующего версии библиотек. С другой стороны, сама возможность настройки виртуального окружения для бесконфликтного существования нескольких версий библиотек очень полезна. Зачастую она позволяет отказаться от изоляции сервисов путем контейнеризации. - **Ряд архитектурных решений,** вызывающих недоумение у выходцев из других языков программирования. Например, в питоне [нет константности](/courses/python/chapters/python_chapter_0020/#block-consts) (ключевого слова `const` или чего-то похожего), а интерпретатор [не блокирует доступ](/courses/python/chapters/python_chapter_0160#block-fields) ко внутренним полям класса и оставляет это на совести разработчика. ## Реализации питона: интерпретаторы [CPython](https://github.com/python/cpython) — самый распространенный интерпретатор питона. Он идет в комплекте большинства Linux-дистрибутивов и без труда ставится почти на любые платформы. CPython написан преимущественно на C и его исходный код выложен в опенсорс. Конечно, есть и другие интерпретаторы. Самые известные: - [PyPy](https://www.pypy.org/) заточен под скорость выполнения. Она достигается за счет JIT-компиляции (компиляции байт-кода в машинный код во время работы программы). - [MicroPython](https://micropython.org/) оптимизирован для запуска на микроконтроллерах. - [IronPython](https://ironpython.net/) написан на C# и позволяет оперировать типами .NET. - [Jython](https://www.jython.org/) — реализация питона на Java, в ней доступны классы Java. Мы будем работать с CPython: это реализация языка, подразумеваемая по умолчанию, когда речь заходит про питон. ## Версии питона Последняя мажорная версия — python 3. [3.12.0](https://docs.python.org/3.12/) — минорный релиз, вышедший в октябре 2023 года. Его мы и будем рассматривать. Питон развивается уже больше **тридцати лет!** За это время самой масштабной поломкой обратной совместимости между версиями был переход с python 2 на 3. В питоне 3 был исправлен ряд недостатков архитектуры языка. Событие позитивное, но есть и обратная сторона. Чтобы мигрировать на новую версию, разработчикам пришлось переписывать тонны кода в уже существующих проектах. Сейчас версия 2 официально не поддерживается. Одним из отличий версии 3 от 2 является правило целочисленного деления. В питоне 2 результат деления целых чисел — также целое. В питоне 3 — вещественное, а для целочисленного деления вместо одной косой черты используется двойная: `//`. Но самое заметное отличие — это отказ от оператора `print` для вывода текста в консоль. В питоне 3 он заменен на функцию `print()`. Перепишите этот код с питона 2 на 3 так, чтобы целочисленное деление осталось целочисленным. {.task_text} ```python {.task_source #python_chapter_0010_task_0050} x = 3/2 print x ``` Для целочисленного деления используйте оператор `//` вместо `/`, для вывода в консоль — функцию `print()` вместо оператора `print`. {.task_hint} ```python {.task_answer} x = 3//2 print(x) ``` И последнее отличие, о котором стоит упомянуть: работа со [строками.](/courses/python/chapters/python_chapter_0100#block-strings) В питоне 2 было определено два строковых типа: `str` и `unicode`. В питоне 3 остался только `str`, зато он может содержать любые юникодные символы. Для обычных байтовых последовательностей используется тип `bytes`. ## Как и кем разрабатывается питон Развитием языка занимается некоммерческая организация [Python Software Foundation.](https://www.python.org/psf/) Новые фичи и изменения синтаксиса вводятся через PEP (Python Enhancement Proposal). PEP — это документ, который может составить и отправить на обсуждение любой желающий. [PEP8](https://peps.python.org/pep-0008/) — официальное руководство по написанию кода на питоне. Ему уже больше 10 лет! Рекомендации PEP8 соблюдает огромное количество опенсорсных и проприетарных проектов. Это де-факто стандарт индустрии по части кодстайла и лучших практик. Для приведения к нему своего кода можно воспользоваться форматтерами и линтерами: [black,](https://github.com/psf/black) [Pylint](https://pypi.org/project/pylint/) и другими. Кстати, [рекомендованная в PEP8](https://peps.python.org/pep-0008/#maximum-line-length) максимальная длина строки — 79 символов. ## Питон — это летающий цирк! Питон назван не в честь змеи. Автор языка Гвидо ван Россум использовал отсылку к шоу [«Летающий цирк Монти Пайтона».](https://en.wikipedia.org/wiki/Monty_Python%27s_Flying_Circus) Того самого, где про Министерство дурацких походок. ...Поэтому единственное, что осталось сделать перед началом разработки на питоне — вывести в консоль `"Hello Monty Python's Flying Circus!"`. {.task_text} ```python {.task_source #python_chapter_0010_task_0060} ``` Нужно вызвать функцию `print()` от строки `"Hello Monty Python's Flying Circus!"`. {.task_hint} ```python {.task_answer} print("Hello Monty Python's Flying Circus!") ``` ![Летающий цирк Монти Пайтона](https://raw.githubusercontent.com/senjun-team/senjun-courses/main/illustrations/python/monty_python.jpg) {.illustration} ## Резюмируем - Питон — интерпретируемый, а не компилируемый язык. - В нем поддерживаются ООП и функциональное программирование. - Типизация неявная, динамическая, строгая. - Любая переменная — это ссылка на объект. - Управление памятью — с помощью подсчета ссылок и сборщика мусора. - Есть интроспекция и рефлексия. - Один из главных недостатков питона — GIL. - CPython — самый распространенный интерпретатор. - Актуальная версия языка — 3. - PEP — документы, в которых описываются изменения языка. - PEP8 содержит рекомендации по кодстайлу и лучшие практики.
Отправка...

Если вам нравится проект, вы можете поддержать его!

Задонатить