НЕКОГДА

УЧИТЬ

Python

Основы Python 3. Интерактивный учебник Клуба Хакеров

От автора

Для прохождения этого самоучителя требуется совсем небольшое время. Он быстро даёт сильный буст для изучения фреймворков и дальнейшего профессионального развития.

В онлайн-интерпретаторе недоступны type() и nonlocal. А в остальном этот учебник прекрасен.

Совет: проговаривайте вслух определения, в которых есть слова, выделенные оранжевым цветом.

Артем Спиридонов, НИИНТ, 2021.

Начало

Если код из какого-то примера не запускается:

  1. Проверьте вложенность скобок, все ли открытые скобки закрыты
  2. Все ли введено правильно
  3. Удалите все отступы и введите их заново, используя только пробелы или только табуляцию (кнопку TAB на клавиатуре). В Python отступы имеют значение

Комментарии

Интерпретатор игнорирует текст, размеченный как комментарии.

Комментарии бывают однострочными и многострочными.

Добавьте однострочный и многострочный комментарии в код программы. Запустите программу, чтобы убедиться в том, что ошибок нет.

Ввод и вывод данных

Программа на Python может вводить и выводить данные.

input() просит пользователя ввести строку текста.

int() приводит данные к целочисленному типу.

print() выводит строку в консоль.

Введите текст этой программы без комментариев, и запустите её.

Переменная — это именованная область памяти.

Каждый раз, когда в программе впервые встречается имя новой переменной и знак присваивания =, интерпретатор сам выделяет область в памяти, даёт ей имя, и записывает туда данные, чтобы потом использовать их.

Типы данных

Мутабельные и иммутабельные типы данных

Мутабельные типы данных создают изменяемые переменные. Их значения могут изменяться в ходе выполнения программы.

Иммутабельные типы данных создают неизменяемые переменные. Их значения не изменяются в ходе выполнения программы. Это хороший способ защитить данные от непреднамеренной модификации. К примеру, настройки и параметры.

Технически в Python нет констант. Вместо них есть иммутабельные типы данных.

Обратите внимание на литералы деклараций типов данных, апострофы и разные скобки. И на запятую в литерале кортежа — этим кортеж отличается от выражения.

Кортеж и словарь — такие же, как и список. Только кортеж иммутабельный, в отличие от обычного списка, его нельзя изменить после создания. А в словаре можно использовать любые индексы. Об этом подробнее ниже.

Литералы

Литералы — как константы. Они не изменяются.

Булевы (логические)

True и False — это числа 1 и 0. Они взаимозаменяемы. 5 + True = 6, а 5 / False выдаст ошибку деления на ноль.

Целые числа
Вещественные числа

Чем отличаются литералы целых и вещественных чисел?

Чем целочисленный ноль отличается от вещественного ноля?

Строковые литералы

Апострофы и кавычки полностью взаимозаменяемы. Их можно чередовать. Если не хотите чередовать, используйте экранирование обратным слешем.

Многострочный строковый литерал так похож на многострочный комментарий, правда?

Список
Кортеж

Почему нет литерала пустого кортежа? Создать его можно, но использовать бессмысленно. Почему?

Словарь

Булев (логический) тип

Булевы литералы
Условия

Условия — это обычные математические выражения, которые просто возвращают булевы значения.

= это оператор присваивания, который создаёт переменную.

== это оператор сравнения, который возвращает булево значение.

!= означает «не равно».

and и or — это тоже самое, что умножение и сложение. В булевой логике они выполняют функции «и» и «или».

Простой пример с логикой «если-то-иначе»

Этот пример похож на предыдущий, но значение вынесено в отдельную переменную, для вашего понимания природы условий.

А это однострочник с тернарным оператором. Он позволяет вставлять условия даже внутрь выражений.

Обратите внимание на ключевые слова if и else.

Давайте напишем программу для проверки чисел на четность.

% возвращает остаток от деления.

0 будет пониматься как False, все остальное — как НЕ False, а значит True.

Функция not() превращает True в False, а False в True.

Это называется инверсией.

Следующий пример работает так же, как и предыдущий.

Циклы с булевыми условиями

Бесконечные циклы используются в программах с графическим пользовательским интерфейсом, к примеру в играх. А также в серверных приложениях, которые нужно запустить так, чтобы они долго работали сами по себе. Когда не нужно завершать выполнение программы до совершения пользователем каких-то действий.

Этот код будет выполняться до тех пор, пока выполнение программы не будет прервано.

А этот код выведет числа от 1 до 10.

break остановит выполнение цикла.

continue прерывает выполнение текущей итерации (повторения) цикла и начинает следующую.

Этот код выведет только четные числа. Попробуйте. А потом попробуйте вывести только нечетные, not(i % 2)

В циклах Python есть else. Если был break, то он не будет выполнен.

Строки

Строковые литералы

\n указывает на конец строки.

Функция len() возвращает количество символов в строке.

Объединение строк называется конкатенацией. Это очень частое действие в программировании.

Этот код не сработает. Почему?

А этот код будет работать. Python забавный =)

Работа со строками

.index() — на какой позиции встречается подстрока?

.count() — сколько раз встречается подстрока?

.startswith() — проверить, что начинается с подстроки

.endswith() — проверить, что заканчивается на подстроку

f-строки сами заботятся о приведении типов

Нарезка [от:до:шаг]

Это очень легко.

Продолжайте пробовать.

Детектор палиндромов. Палиндром — слово которое читается одинаково слева направо и справа налево.

Синтаксис лямбда-функции описан ниже. Вернитесь к этому примеру потом.

.replace(из, на) — строковая замена

S-строки

  • %s — строки (или любой объект, который можно показать как строку, например числа)
  • %d — целые числа
  • %f — вещественные (дробные) числа
  • %.сколькознаковf — указать сколько показывать знаков после запятой.
  • %x/%X — шестнадцатеричное представление числа (со строчными или ЗАГЛАВНЫМИ буквами)

Ещё пример.

Списки

Литерал списка

.append(что) — добавить в конец списка.

.insert(куда, что) — вставить в указанное место.

Списки можно легко объединять.

Списки удобно итерировать (перебирать) циклами.

В обратном порядке? Это тоже легко.

Можно получать элементы по индексу.

Нарезка [от:до:шаг]

Обратите внимание, как это похоже на работу со строками. Прекрасно!

Обработка списков

Списки можно итерировать (перебирать).

А можно сделать однострочник.

map(функция, список) — применяет функцию к каждому элементу списка.

filter(функция, список) — удаляет элементы по ответу от проверяющей функции.

С помощью лямбда-функции можно делать красивые однострочники

lambda аргумент: возвращаемое значение

Оператор in проверяет, входит ли значение в перечисление.

Генераторы

Генераторы — это простые функции, которые возвращают итерируемое множество элементов по одному за раз.

Генератор запускается оператором for. Как только код функции генератора достигает оператора «выход» yield, генератор передает свое выполнение обратно в цикл for, возвращая новое значение из множества. Генератор может генерировать любое количество значений, выдавая их по очереди.

Генераторы списков и однострочники

Функция range(от, до, шаг) возвращает последовательность чисел.

Вот такой код...

...можно упростить до такого

Генераторы списков (List Comprehensions) — это более изящная форма для записи циклов обработки списков.

Синтаксис тоже прост: [что откуда какие]. Можно посмотреть много примеров с однострочниками на канале Клуба Хакеров.

Ещё можно отметить, что такие программы быстрее работают. Это бывает критичным при больших объёмах данных, например в Data Science, или при высоких требованиях к быстродействию.

Числа

Целые или вещественные числа можно создать с помощью литералов.

Приведение типов может быть явным.

Словари

Словари — они как списки. Только для доступа используются не индексы, а любые объекты.

Можно добавлять новые элементы и получать доступ к ним.

Словари можно перебирать точно так же, как и списки.

Метод .items() возвращает генератор. Копия данных при этом не создаётся.

Можно удалить строчку из словаря.

Или так

Множества

Множества set — это списки без повторов.

split() разделяет строку в список, а set() приводит список в множество и таким образом удалит повторы.

С помощью множеств удобно вычислять пересечения списков.

Организация кода

Функции

Процедура — это последовательность действий.

Процедура, которая принимает и возвращает значения, называется функцией.

Процедура и функция являются частями кода, предназначеными для многократного использования.

Картинка для понимания анатомии функции:

Функция принимает и возвращает значения. Хотя это и не обязательно.

Оператор def указывает на то, что создаётся новая функция.

Оператор return возвращает значение функции и прерывает её работу.

Аргументы (параметры) передаются функции в скобках. Тело этой функции отделено от другого кода отступом. В конце определения названия и аргументов функции стоит двоеточие.

Можно задать аргументы по умолчанию.

Функция может иметь переменное количество аргументов.

Лямбда-функция — это короткая запись функции.

Синтаксис лямбда-функции: lambda параметры: возвращаемое значение

Следующая тема про функции чуть сложнее. Но не беспокойтесь, вы будете редко пользоваться этим. Замыкание — это функция внутри функции, которая также может запоминать ранее переданные значения.

Создавая код классов, вам может понадобится заглушка для тел функций, которые пока не заполнены кодом. Вы можете использовать оператор pass, что означает «пропустить».

Код класса тоже можно «пропустить».

Реструктурирующее присваивание

Следующие два примера кода идентичны.

Таким способом можно распаковать список или кортеж. Это удобно для реализации разных архитектурных паттернов.

Обработка исключений

Можно создавать код, более устойчивый к ошибкам.

Для этого есть блоки try/except.

ООП: классы и объекты

ООП — объектно-ориентированное программирование. Это способ программирования с использованием классов и объектов.

Объект — это программная сущность, в которой есть функции и переменные.

Функции объекта называются методами.

Переменные и константы объекта называются свойствами.

Класс — это программа, с помощью которой создаются объекты.

Чем объект отличается от класса?

Класс

Объект

Абстрактен. Это программа, которая описывает объект Материален. Это экземпляр класса — объект создаётся из класса во время выполнения программы
Программист создаёт классы. Классы — это части программы Объекты создаёт интерпретатор (или ОС) из классов, во время выполнения программы
У класса могут быть методы и свойства (функции и переменные). Они будут у объектов этого класса. У объекта могут быть методы и свойства (функции и переменные). Как в классе задано, из которого сделан объект — то в нём и будет

Обычно имена классов пишут с большой буквы. Имена объектов — с маленькой.

Определение класса выглядит так:

Создадим объект из этого класса.

Можно получить доступ к свойству объекта.

Сеттеры и геттеры

Можно продемонстрировать свое прекрасное воспитание и хорошие манеры, если не лезть напрямую в свойства объекта, а использовать специальные методы — сеттеры и геттеры.

Сеттер, от английского set — устанавливать.

Геттер, от английского get — получать.

self — это ссылка на объект, созданный из этого класса. Как обратиться к методу или свойству объекта изнутри? Через self.

Зачем нужны сеттеры и геттеры?

Во-первых, во время записи и считывания свойств при дальнейшей разработке программы могут быть выполнены любые действия. Вы создаёте отличный каркас, логичный и понятный, для комфортной разработки.

Во-вторых, вы не вставляете палки в колеса и не создаёте самому себе проблем, напрямую записывая и считывая свойства. Измениться может что угодно — от имени этих свойств, до типов данных, способов извлечения и получения и многое другое. Изменения в одном месте не должны влечь массовые изменения в других частях программы.

Мораль: каждому классу — отдельный файл. Помещайте по одному классу в один файл. Имя файла должно точно соответствовать имени класса. Это очень удобно.

Про модули и пакеты рассказано ниже.

Конструктор — это приватный метод, который автоматически выполняется при создании объекта из класса.

Конструктор создаётся с помощью ключевого слова __init__()

Конструктор выполняется автоматически при создании нового объекта класса.

Наследование

При создании новых классов можно наследовать методы и свойства от других классов.

Класс-родитель указывается в скобках при создании дочернего класса.

Следующие темы к «Основам» уже не относятся. Это скорее практика.

Модули

Модули в Питоне — это просто файлы, с раcширением .py

В модуле могут быть функции, классы и переменные.

Файл program.py содержит основные функции программы. А в файл database.py выделены функции для работы с базой данных. Иными словами, модуль database содержит логику, которая позволяет работать с базой данных.

Модули импортируются из других модулей с помощью команды import.

Для следующих примеров онлайн-интерпретатор не подойдёт. Установите Python на свой компьютер или в виртуальную машину.

Создайте файл program.py

После запуска program.py мы можем увидеть, что выполнены функции из обоих файлов.

Для того, чтобы вызвать функцию из модуля, сначала указывается имя модуля, а потом, через точку, имя функции.

При запуске этой программы появилась директория `__pycache__ ` с файлами *.pyc. Питон компилирует файлы в байт-код, поэтому ему не нужно анализировать файлы каждый раз при загрузке модулей. Если файл pyc существует, он загружается вместо файла py, и вы можете контролировать это.

Импорт объектов модулей в текущее пространство имен

Вы можете импортировать модуль в текущее пространство имён с помощью команды from.

Теперь для вызова функции get_data не надо использовать префикс с точкой database.

Удобство заключается в том, что теперь не нужно указывать, из какого именно модуля вы взяли эту функцию. В тоже время, в любом пространстве имён не может быть двух объектов с одинаковыми именами, поэтому импорт заменяет существующий объект.

Импорт всех объектов из модуля

Звездочка * означает "всё". Кстати, не только в Python.

Это несколько рискованно, так как можно импортировать то, что перепишет то, что у вас уже есть, или не должно быть переписано.

Вы можете переименовывать модули при загрузке.

Можно добавить логику переименования

В примере выше, переменная threed должна содержать False, если не требуется 3Д-отрисовка. И True, если требуются визуализация в 3Д, и платформа пользователя поддерживает её. В зависимости от доступности и востребованности 3Д-режима визуализации, будут использоваться два разных модуля под одинаковым именем. Если в этих модулях заданы одноименные функции для визуализации — остальной код программы может и не догадываться о том, как именно производится визуализация в данный момент.

Инициализация модулей

При первой загрузке модуля он инициализируется сам однократным исполнением его кода. Если другой модуль снова импортирует этот же модуль, он не будет загружен дважды — поэтому локальные переменные внутри модуля действуют по паттерну проектирования Синглтон — они инициализируются только один раз.

Полезно знать, что вы можете положиться на это поведение при инициализации объектов.

Указание пути загрузки модуля

Можно указывать Python, где находятся модули, которые вы хотите загружать.

Это выполнит crm.py, и включит загрузку скриптов из директории /dir как будто это локальная директория.

А ещё можно использовать функцию sys.path.append. Её надо использовать *перед* командой import.

Встроенные функции

Встроенных функций очень много. Можно исследовать их тут: https://docs.python.org/3/library/

При изучении этих функций пригодятся две очень важные офункции — dir и help.

Можно посмотреть список функций, к примеру в консоли Python3

>>> import numpy
>>> dir('numpy')
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

С помощью команды help можно открыть справку

Создание пакетов

Пакеты — это просто директории с модулями.

Каждый пакет Python 3 должен быть директорией, в которой должен быть специальный файл __init__.py

Этот файл может быть пустым, и именно он показывает Питону, что эта директория — его пакет, и что его можно импортировать.

Имя директории должно соответстовать имени пакета.

Практикум

Однострочники

Вот несколько полезных однострочников из статьи Abhay Parashar.

Попробуйте самостоятельно проанализировать и изменить их.

Популярная задача на собеседованиях. Напечатать список чисел, вывести Fizz вместо чисел, кратных 3, и Buzz, вместо чисел, кратных 5. Если число кратно и 3, и 5, тогда вывести FizzBuzz.

Найдём простые числа?


Основы Python 3. Онлайн-учебник Клуба Хакеров
НИИНТ, 2021