Python предоставляет большой набор встроенных функций, некоторыми из которых мы уже пользовались, например, print() для вывода данных на экран или len() для определения количества элементов в коллекции. Исходный код большинства встроенных функций написан на том же языке, что и сам интерпретатор Python. И если наиболее используемым интерпретатором является CPython, написанный на C, то и код многих функций написан на C. Но существует поддержка и других языков, например, интерпретатор Jython использует язык программирования Java, а IronPython – C#.
Функции, написанные один раз, можно использовать бесконечное количество раз без необходимости повторного написания их кода. Это позволяет следовать одному из основополагающих принципов программирования DRY (от англ. Don’t Repeat Yourself – Не повторяйтесь), который заключается в том, что следует избегать избыточного дублирования кода.
В случае встроенных функций, нам не нужно знать, как именно они реализованы, для того чтобы их использовать. У каждой функции есть имя, по которому её можно вызвать, она может принимать определённые параметры и совершать определённые действия.
Множества в Python пришли из математики, где над ними можно совершать такие операции как объединение и пересечение, а также находить разность и симметричную разность.
Рассмотрим два множества: красные яблоки и зелёные груши. При этом оба множества содержат жёлтые яблоки и груши:
set1 = {"Красные яблоки", "Жёлтые яблоки", "Жёлтые груши"}
set2 = {"Зелёные груши", "Жёлтые груши", "Жёлтые яблоки"}
Объединение двух множеств – это новое множество, которое содержит все элементы обоих множеств. В математике объединение двух множеств A и B обозначается как A ∪ B.
Для того, чтобы наглядно представить множества и отношения между ними, используем круги Эйлера. Каждый круг представляет одно множество, а область внутри него – его элементы. Перекрывающиеся области между кругами показывают элементы, которые являются общими для этих множеств.
Параметры – это переменные, которые функция использует для получения значений, переданных ей при вызове. Они позволяют функции работать с данными, переданными извне, делая её более гибкой и универсальной. Значения, которые передаются функции при её вызове, называются аргументами.
Например, встроенная функция sum() возвращает сумму всех элементов коллекции. При этом коллекция должна быть передана как первый аргумент функции, а значение параметра start, определяющее начальное значение суммы, может быть не указано вовсе, передано по имени или как второй аргумент функции:
numbers = [1, 2, 3]
print(sum(numbers))
# Вывод: 6
print(sum(numbers, start=10))
# Вывод: 16
print(sum(numbers, 10))
# Вывод: 16
Таким образом, значения параметров, то есть аргументы, могут быть переданы функции по позиции или по имени. А сами параметры функции делятся на обязательные и необязательные. Обязательные параметры должны быть переданы при каждом вызове функции, в то время как необязательные параметры могут быть опущены, и для них будет использовано значение по умолчанию.
Вместе с установкой интерпретатора Python вы получаете большой набор готовых инструментов, собранных в стандартной библиотеке Python. Модули, входящие в неё, считаются неотъемлемой частью языка, что позволяет не устанавливать дополнительные пакеты и решать самые разные задачи: математические вычисления, генерация случайных чисел, работа с датой и временем, и много другое.
Среди всего многообразия модулей стандартной библиотеки модуль math является незаменимым помощником, когда речь заходит о более сложных математических вычислениях, которые выходят за рамки базовых арифметических операций, рассмотренных ранее.
Для использования функций и констант из этого модуля его следует импортировать:
import math
Многие программы должны учитывать дату и время, например, при регистрации нового пользователя, создании заказа в интернет-магазине или планировании каких-то событий.
Модуль datetime в Python является основным инструментом для работы с датой и временем. Он предоставляет классы, которые позволяют хранить и манипулировать датой и временем. Для этого в нём определены четыре основных класса:
date – дата
time – время
datetime – дата и время
timedelta – временной промежуток
Для использования этих классов их следует импортировать из модуля datetime:
from datetime import date, time, datetime, timedelta
Любой объект создаётся на основе класса, который является шаблоном, определяющим свойства и поведение объекта. Поэтому такой объект ещё называют экземпляром класса. Может быть вы помните, что функция type() возвращает конструкцию class <тип>. Это связано с тем, что все встроенные типы данных являются классами. Например, строка "Привет!" является объектом или экземпляром класса str и поддерживает всего его свойства и методы.
И мы можем не только использовать встроенные классы, но и создавать свои собственные. Давайте создадим класс для автомобиля в автосалоне. Для этого нам понадобится ключевое слово class, за которым следует имя класса, написанное с большой буквы. Если названия переменных и функций мы писали в «змеином регистре» snake_case, то классы принято именовать в «верблюжьем регистре» CamelCase. То есть каждое слово начинается с заглавной буквы и без разделителей следует за предыдущим:
class Car:
pass
Здесь мы создали пустой класс Car с помощью уже знакомого нам ключевого слова pass.
Возможности перегрузки операторов в Python не ограничиваются базовыми арифметическими операциями и сравнением объектов, так как существуют методы, позволяющие создать свою собственную коллекцию, то есть класс, представляющий собой контейнер элементов, как список или словарь. Объекты такого класса могут быть перебраны в цикле for, использовать оператор in и функцию len(), а также синтаксис обращения по индексу или ключу через квадратные скобки.
Методы __iter__() и __next__() лежат в основе механизма итерации в Python и позволяют перебирать объекты в цикле for или использовать их в других функциях, которые принимают итерируемый объект, например, sum() или zip(). Также эти методы можно явно вызывать с помощью функций iter() и next(), как мы уже делали для встроенных типов данных, когда рассматривали работу итерируемых объектов.
Метод __iter__() превращает объект в итератор. В простейшем случае, сам итерируемый объект часто выступает в роли своего итератора, поэтому __iter__() просто возвращает self.
Рекурсия – это способ решения задачи, при котором функция вызывает сама себя, и такая функция называется рекурсивной.
Рекурсия позволяет, не используя цикл, разбить задачу на более мелкие, идентичные части и решать каждую из них с помощью того же самого алгоритма. Это похоже на ситуацию, когда для выполнения задания часть работы передаётся тому же исполнителю, но в более простом виде.
Рекурсия состоит из двух ключевых компонентов:
- Базовый случай – это условие, при котором функция прекращает вызывать саму себя. Он является точкой выхода и предотвращает бесконечные вызовы.
- Рекурсивный случай – это часть, где функция вызывает саму себя, но с измененными аргументами, чтобы каждый следующий вызов приближал функцию к базовому случаю.
Модуль os (от англ. Operating System – операционная система) является одним из наиболее часто используемых модулей в Python. Он предоставляет программам возможность взаимодействовать с операционной системой (ОС), на которой они запущены.
Это означает, что с помощью модуля os вы можете выполнять те же операции, которые обычно делаете через командную строку или Проводник, но программно, прямо из вашего кода Python.
Главное преимущество модуля os заключается в его кроссплатформенности: он скрывает различия между операционными системами. Например, функция os.remove() удалит файл как в Windows, так и в Linux, хотя базовая системная команда для этого на этих ОС разная. Это позволяет писать код один раз, и он будет работать везде, где установлен Python.
Программируя на Python, мы уже сталкивались как с функциями, так и с методами. Функции не привязаны к объектам и вызываются независимо от них. Например, функция id() возвращает уникальный идентификатор объекта, а функция print() выводит данные на экран.
Однако методы, напротив, принадлежат определённым типам данным (классам) и используются только совместно с объектом, к которому относятся. Например, уже рассмотренный метод dict.values() возвращает последовательность значений словаря dict.
Строки имеют большое количество методов, позволяющих совершать разные действия над ними, например, привести все символы строки к верхнему регистру или обрезать пробелы в начале и конце строки.
Но строки являются неизменяемым типом данных, поэтому методы, преобразующие строку, на самом деле не изменяют её, а возвращают изменённую копию исходной строки, которую следует сразу использовать в работе или присвоить какой-либо переменной.