Написание сложной программы с нуля, в котором весь код содержится в одном огромном файле, может быть невероятно долгим и трудозатратным. Гораздо эффективнее не только разбить программу на отдельные файлы (и папки), но и использовать уже готовые части кода – те, что вы ранее написали сами или те, что были разработаны и протестированы другими специалистами.
Файл с расширением .py называется модулем, а имя этого файла является именем модуля. При этом все переменные, функции и классы из одного модуля можно свободно использовать в других модулях. Если код в файле предназначен для непосредственного запуска, а не для повторного использования, то такой файл часто называют скриптом.
Набор связанных модулей, которые совместно обеспечивают определённую функциональность, называется пакетом. Он представляет собой папку, которая содержит несколько файлов с расширением .py и часто содержит специальный служебный файл __init__.py, обозначающий, что эта папка является пакетом.
Библиотека является более общим понятием, так как в программировании под ней понимают набор готового кода, который можно повторно использовать в своём проекте. Библиотека в Python может быть представлена как одним модулем, так и пакетом, который, в том числе, может содержать другие пакеты.
В большинстве реальных приложений недостаточно просто обрабатывать данные в оперативной памяти, так как часто требуется сохранять информацию между запусками программы или загружать ее из внешних источников. Для этого используется работа с файлами на диске.
По способу хранения информации все файлы делятся на текстовые и бинарные (двоичные).
Байты внутри текстового файла представляют символы (с учётом используемой кодировки), которые мы можем прочитать и увидеть на экране. Такие файлы удобны для хранения текстовой информации.
В бинарных файлах байты не соответствуют символам напрямую, а представляют собой различные структуры данных: машинные инструкции, пиксели изображений, аудиоданные и другие элементы, в зависимости от формата файла. Поэтому бинарные файлы не предназначены для непосредственного чтения человеком.
Текстовые форматы, например, CSV и JSON могут сериализовать (преобразовать в текст) только базовые типы: строки, числа, списки и словари, однако они не позволят сохранить данные более сложных типов, например, экземпляры классов.
Модуль pickle был создан специально для решения этой проблемы. С английского слово «pickle» переводится как «соленья», что является метафорой для «консервирования» данных.
Ключевой особенностью модуля pickle является использование двоичного формата хранения данных. Он не пытается быть читаемым человеком, а сосредоточен на сохранении внутренней структуры объекта. По этой причине файлы, созданные с помощью pickle, всегда открываются в двоичном режиме (с буквой «b» в конце, например, "rb" или "wb").
Ранее мы уже научились запускать через терминал программы на Python, написанные в Блокноте. Это полезно для простых задач и экспериментов, но для более серьезной разработки он неэффективен. Постоянное переключение между текстовым редактором и терминалом существенно замедляет работу.
Чтобы сделать процесс написания кода более эффективным и приятным, программисты используют специальные программы – редакторы кода, которые обладают множеством полезных функций, таких как:
- Подсветка синтаксиса, которая выделяет разные элементы кода разными цветами, что облегчает чтение и написание программы
- Автодополнение кода, когда редактор предлагает варианты завершения набираемых слов и конструкций, что ускоряет написание кода и помогает избежать опечаток.
- Отладка кода с помощью встроенных инструментов, которые позволяют пошагово выполнять программу и находить ошибки.
- Интеграция с системами контроля версий (например, Git) для удобного управления изменениями в коде и совместной работы над проектами.
- Поддержка множества языков программирования.
- Расширяемость путём добавление новых функций с помощью плагинов (расширений).
Anaconda Toolbox – это расширение для Jupyter Notebook и JupyterLab, которое позволяет синхронизировать проекты с облаком Anaconda, сохранять сниппеты кода и использовать уже готовые среды. Также через это расширение вы получаете доступ к ИИ-помощнику Anaconda Assistant.
Для полноценной работы с этим инструментом требуется регистрация, поэтому если вы не зарегистрировались на этапе установки Anaconda, то вы можете сделать это сейчас на официальном сайте.
Установить Anaconda Toolbox можно через Anaconda Navigator. Для этого просто найдите его в списке приложений на вкладке Home и нажмите кнопку Install.
Также его можно установить через менеджер conda:
conda install anaconda-toolbox
Важной частью любой программы являются операции ввода-вывода: получение данных от пользователя и отправка результатов обратно. В самом простом виде в Python это реализуются в виде двух встроенных функций: уже знакомой нам функции print() для вывода данных на экран, и функции input() для получения данных от пользователя.
Функция print() – одна из наиболее используемых функций в Python, позволяющая выводить различные объекты на экран.
По умолчанию все объекты разделяются пробелом, а в конце добавляется символ переноса строки (\n), поэтому каждый следующий вызов функции print() выводит данные на новой строке. Однако такое поведение можно изменить с помощью параметров sep (от англ. separator – разделитель) и end (c англ. – конец).
При изменении параметра sep все значения разделяются между собой его значением, а не пробелом. В качестве разделителя можно передать любую строку:
print(1, 2, 3, sep=" | ")
# Вывод: 1 | 2 | 3
print("Ручка", "Карандаш", "Линейка", sep="_")
# Вывод: Ручка_Карандаш_Линейка
print("x", "y", "z", sep="\t")
# Вывод: x y z
В реальной жизни данные редко хранятся в виде сплошного текста. Чаще всего они представляют собой структурированные данные, например, таблицы или словари, поэтому для их эффективного хранения требуется не просто текстовый формат .txt, а более специализированные форматы, устанавливающие строгие правила для организации данных. Например, для хранения табличных данных часто используются CSV-файлы (от англ. Comma-Separated Values – значения, разделённые запятыми).
Стандартная библиотека Python предоставляет набор модулей, позволяющий работать с файлами различных форматов, в том числе, с CSV-файлами. Для этого предназначен модуль csv, который берёт на себя всю работу по кодированию, декодированию и обработке специальных символов, позволяя программисту сосредоточиться на работе с данными.
Несмотря на то, что коллекции в Python имеют свои уникальные особенности, они обладают некоторыми общими способами работы с ними. Так мы можем получить количество элементов любой коллекции и проверить принадлежность элемента ей, а также определить максимальное и минимальное значение или посчитать сумму коллекции чисел.
Мы уже встречались с функцией len(), когда говорили о переборе элементов упорядоченных коллекций по индексу. Но она позволяет узнать, сколько элементов содержится в любой встроенной коллекции Python.
Например, определим количество элементов в множестве:
weapons = ("Меч", "Лук", "Копье")
print(len(weapons))
# Вывод: 3
Помимо базовых арифметических операций, Python предлагает набор встроенных функций, которые помогают работать с числами – это функция abs(), возвращающая модуль числа, функция round() для округления чисел, и функция pow(), эквивалентная оператору возведения в степень.
Функция abs() (от англ. absolute — абсолютный) позволяет получить абсолютное значение числа, то есть его модуль. В математике модуль представляет собой расстояние на числовой прямой от этого числа до 0. И так как расстояние не может быть отрицательным, то можно сказать, что модулем числа является это же число, но без учёта знака.
Функция abs() очень проста в использовании и в любом случае возвращает положительное значение этого же числа:
print(abs(5))
# Вывод: 5
print(abs(-10))
# Вывод: 10
print(abs(-3.14))
# Вывод: 3.14
Встроенные типы данных поддерживают множество стандартных операций. Например, числа поддерживают все арифметические операции, а строки мы можем складывать и умножать на число.
Однако, когда вы создаёте собственный класс, Python использует поведение по умолчанию и не знает, какое логическое значение вы вкладываете в операции сложения или сравнения для объектов этого класса.
Например, давайте вспомним, что в математике есть такое понятие как вектор – направленный отрезок, соединяющий две точки. Тогда координатами вектора AB с началом в точке A с координатами (x1; y1) и концом в точке B с координатами (x2; y2) является разность соответствующих координат конца и начала, то есть (x2 - x1; y2 - y1). Поэтому при создании класса вектора Vector мы можем инициализировать его координатами x и y, представляющими собой его смещение относительно начала координат:
class Vector:
def __init__(self, x: int | float, y: int | float):
self.x = x
self.y = y
def __repr__(self) -> str:
return f"Vector(x={self.x}, y={self.y})"