Понимание модулей Python и способов их использования для лучшей организации растущей базы кода.

Любой, у кого есть опыт написания кода на Python, должен быть знаком с операторами типа import x или его вариантами. Это способ, с помощью которого Python позволяет своим пользователям использовать дополнительные функции в виде модулей и функций. В этом посте мы попытаемся понять модули Python.

Вещи, которые будут обсуждаться:

  1. Что и почему?
    — Что такое модуль?
    — Почему полезно использовать модуль
    — Понимание пространства имен
  2. Как использовать модуль?
    — Различные способы импорта модуля и его компонентов
    — Демонстрация полезности модулей
    — Как проверить компоненты модуля
  3. Встроенные модули
  4. Следующие шаги

Что и почему?

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

"Модуль — это файл, содержащий определения и операторы Python". — Источник: Учебник по Python

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

  • Прямое копирование и вставка функций в каждый проект или
  • Сохранение их в скрипте и запуск скрипта во время проекта. Например, для запуска такого скрипта можно использовать волшебную команду %run.

Первый вариант имеет очевидное ограничение повторных работ. Хотя второй вариант является лучшей идеей, но имеет следующие ограничения:

  • Выполняя скрипт, вы, по сути, создаете все переменные и функции, доступные внутри скрипта. Таким образом, вы загружаете свое рабочее пространство всеми компонентами этого скрипта, даже если вам нужны только избранные.
  • Кроме того, созданные объекты будут занимать пространство имен, что может привести к конфликту имен или непредвиденным последствиям. Подробнее о пространстве имен позже.
  • В-третьих, в крайних случаях это может подвергнуть вас риску, особенно если вы работаете над открытым проектом или используете чужой скрипт. Если вы выполняете такой сценарий вслепую, вы можете в конечном итоге запустить какой-то вредоносный код, который может разоблачить вас в чьих-то злых намерениях.

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

💡 Примечание о пространстве имен

Мы говорили о термине — пространство имен. Проще говоря, пространство имен — это пространство памяти, выделенное на компьютере, где существуют имена объектов. Внутри пространства имен имена уникальны внутри пространства имен. Если рассматривать пространства имен как группы, то в разных группах могут быть члены с одинаковыми именами, но внутри группы не будет повторяющихся имен. Использование модулей — отличный способ сохранить пространство имен отдельным и чистым.

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

Демонстрационный подраздел в следующем разделе должен прояснить ситуацию.

Как использовать модуль?

Давайте сначала создадим скрипт Python с именем messingAround.py и сохраним его в том же каталоге, где мы будем запускать нашу программу Python. Это будет домом для наших функций и переменных. Для начала определим одну переменную — pi = 6.38 и одну функцию — makeHalf() внутри messingAround.py. Итак, скрипт будет выглядеть так:

# messingAround module
pi = 6.38
def makeHalf(val):
    return val/2

Способы импорта

Чтобы сделать модуль доступным, мы должны импортировать его, используя ключевое слово import. Существуют разные способы импорта модулей. На примере messingAround мы увидим разные способы импорта модулей:

  • Мы можем импортировать весь модуль, просто вызвав import messingAround.
    — Это сделает все компоненты модуля доступными для вызова. Но не будет загружать их как объекты Python.
    — Мы также можем вызывать несколько модулей в одной строке, например import <module01> <module02>.
  • Мы можем импортировать определенный компонент из модуля. В нашем примере мы могли бы загрузить pi из модуля messingAround, вызвав from messingAround import pi.
    — Мы также можем импортировать несколько компонентов из одного модуля, используя одну строку, добавив имена компонентов, разделенные запятой: from module01 import component01, component02.
  • Мы можем давать псевдонимы либо модулю, либо компонентам во время их импорта:
    — Импорт messingAround как ma: import messingAround as ma.
    — Импорт component01 как c01, component02 как c02: from module01 import component01 as c01, component02 as c02.
    — 🚨 Помните , если вы указываете псевдонимы при импорте, вам придется вызывать их по псевдониму. Называть их настоящими именами уже не получится.
  • Мы можем загрузить все из модуля, вызвав from messingAround import *.
    — 🚨Вряд ли вы захотите это сделать. По сути, это то же самое, что и выполнение скрипта, но со всеми ограничениями, которые мы обсуждали ранее.

Демо

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

Импорт модуля и использование его компонентов

import messingAround as ma
import math as m
pi = m.pi * 3
print("My pi value = {} \nmessingAround's pi value = {} \nMath module's pi value = {}".format(pi, ma.pi, m.pi))
My pi value = 9.42477796076938 
messingAround's pi value = 6.28 
Math module's pi value = 3.141592653589793

Модуль Math поставляется с переменной pi, которая содержит значение π. У нас также есть переменная с тем же именем, но другим значением в нашем модуле. Кроме того, мы создали пользовательскую переменную pi, используя переменную pi из модуля math.

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

Использование волшебных команд и импорт *

Наоборот, рассмотрим следующий пример.

# import *
from messingAround import *
import math as m
print("pi value = {} \nMath module's pi value = {}".format(pi, m.pi))
print()
pi = m.pi * 3
print("pi value = {} \nMath module's pi value = {}".format(pi, m.pi))
pi value = 6.28 
Math module's pi value = 3.141592653589793
pi value = 9.42477796076938 
Math module's pi value = 3.141592653589793

Обратите внимание, как постоянно меняется значение pi!

  • Как только мы загрузили все из модуля messingAround, в нашей рабочей области была создана переменная с именем pi — проверьте распечатанное значение 6.28.
  • Но как только мы создали новую переменную и дали ей такое же имя — pi, исходная переменная, загруженная из модуля messingAround, была заменена этой новой переменной. Проверьте, как изменилось значение pi позже.
  • Обратите внимание, что значение переменной pi из модуля math остается прежним.

🛑 Замените эту строку from messingAround import * на %run -i messingAround.py. Результаты такие же? Подумайте о «Почему»?

Заглянуть внутрь модуля

Когда модули становятся больше, мы можем захотеть проверить, что находится внутри модуля сразу после его импорта. dir() позволяет нам сделать именно это. dir(<module name/alias>) распечатывает компоненты в алфавитном порядке.

dir(ma)
['__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 'makeHalf',
 'pi']

Обратите внимание, как в выводе перечислены два наших компонента makeHalf и pi. На данный момент игнорируйте компоненты со всеми символами подчеркивания. Мы вернемся к ним, когда будем обсуждать создание пакета Python.

Встроенные модули и указатель модулей Python

Когда мы устанавливаем Python, мы получаем вместе с ним кучу модулей. Если рассматривать Python как автомобиль, то только сама программа Python похожа на базовую модель, а все модули — на надстройки/апгрейды. Все эти модули вместе со встроенными функциями называются Стандартной библиотекой Python.

Чтобы найти обширный список модулей Python, вы можете посетить официальный сайт Python Module Index. Слово предостережения, хотя,

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

Что дальше?

Понимание модулей — это первый шаг к пониманию Пакетов Python. Пакет практически представляет собой набор модулей. В этом посте мы узнали о модулях, преимуществах использования модулей и о том, как их использовать. В следующем посте мы узнаем, как организовать наши модули в пакете.

Обновление. Прочтите следующий пост, чтобы узнать, как получить доступ к пакетам из модулей:



Спасибо, что прочитали этот пост. Если вам понравился этот пост, ознакомьтесь с моей серией Объектно-ориентированное программирование на Python здесь: https://medium.com/@curious-joe.