Импорт модулей и пакетов в Python

PythonBeginner
Практиковаться сейчас

Введение

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

Затем вы попрактикуетесь в двух основных способах импорта кода из модулей в вашу программу: оператор import для загрузки всего модуля и оператор from...import для загрузки определенных функций или переменных. Наконец, вы узнаете, как структурировать связанные модули в пакет для создания хорошо организованного и масштабируемого проекта. Все кодирование будет выполняться в WebIDE с использованием файлов Python и терминала.

Понимание модулей Python

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

В вашем WebIDE вы увидите проводник файлов (file explorer) слева. В лабораторной среде уже создан файл с именем hello.py в директории ~/project.

Сначала откройте hello.py, чтобы изучить его содержимое. Он должен содержать следующий код:

print("This code runs on import or direct execution.")

if __name__ == "__main__":
    print("This code runs ONLY when the script is executed directly.")

Блок if __name__ == "__main__": является специальной конструкцией в Python. Переменная __name__ — это встроенная переменная, которая принимает значение имени текущего модуля. Когда скрипт Python запускается напрямую из командной строки, его __name__ устанавливается в строку "__main__". Это условие if позволяет вам писать код, который будет выполняться только тогда, когда файл запускается как основная программа, а не когда он импортируется другим модулем.

Давайте посмотрим на это в действии. Откройте терминал в вашем WebIDE и запустите скрипт hello.py напрямую:

python3 hello.py

Вы увидите следующий вывод, поскольку выполняются обе инструкции print:

This code runs on import or direct execution.
This code runs ONLY when the script is executed directly.

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

Импорт модулей с помощью оператора import

Наиболее распространенный способ использования модуля — импортировать его с помощью оператора import. Это делает весь код модуля доступным для вашего текущего скрипта.

В проводнике файлов вы найдете пустой файл с именем main.py. Это будет наш основной скрипт для остальной части лабораторной работы.

Откройте main.py и добавьте следующую строку для импорта модуля hello:

import hello

print("The main.py script has finished.")

Сохраните файл. Теперь запустите main.py из терминала:

python3 main.py

Внимательно посмотрите на вывод:

This code runs on import or direct execution.
The main.py script has finished.

Обратите внимание, что была выполнена только первая инструкция print из hello.py. Код внутри блока if __name__ == "__main__": был пропущен. Это связано с тем, что когда main.py импортирует hello, переменной __name__ в контексте hello.py присваивается значение "hello" (имя модуля), а не "__main__". Эта особенность необходима для создания многократно используемых модулей, которые не вызывают нежелательных побочных эффектов при импорте.

Теперь давайте поработаем с модулем, который содержит не только операторы вывода. Откройте файл module_a.py. Он содержит переменную, функцию и класс.

PI = 3.14159

def greet(name):
 print(f"Hello, {name} from module_a!")

class Calculator:
    def add(self, x, y):
        return x + y

Измените main.py так, чтобы он импортировал module_a и использовал его члены. Для доступа к члену импортированного модуля используется синтаксис module_name.member_name.

Замените содержимое main.py следующим:

import module_a

## Access the PI variable
print(f"The value of PI is {module_a.PI}")

## Call the greet function
module_a.greet("LabEx")

## Create an instance of the Calculator class and use its method
calc = module_a.Calculator()
result = calc.add(5, 3)
print(f"5 + 3 = {result}")

Сохраните файл и запустите его:

python3 main.py

Вывод будет следующим:

The value of PI is 3.14159
Hello, LabEx from module_a!
5 + 3 = 8

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

Импорт конкретных объектов с помощью from...import

Иногда вам нужны только определенные элементы из модуля. Оператор from...import позволяет импортировать конкретные функции, классы или переменные непосредственно в пространство имен (namespace) вашего текущего скрипта. Это означает, что вы можете использовать их без префикса module_name..

Давайте модифицируем main.py для использования этого метода импорта. Вместо импорта всего module_a мы импортируем только переменную PI и функцию greet.

Обновите main.py следующим кодом:

from module_a import PI, greet

## Access PI and greet directly without the module prefix
print(f"The value of PI is {PI}")
greet("World")

Сохраните файл и запустите его из терминала:

python3 main.py

Вывод будет следующим:

The value of PI is 3.14159
Hello, World from module_a!

Как видите, PI и greet используются напрямую. Однако, если вы попытаетесь получить доступ к тому, что вы не импортировали, например, к классу Calculator, вы получите ошибку.

Попробуйте это сейчас. Добавьте следующие строки в конец main.py:

calc = Calculator()
print(calc.add(10, 20))

Запустите скрипт снова:

python3 main.py

На этот раз скрипт завершится с ошибкой NameError:

The value of PI is 3.14159
Hello, World from module_a!
Traceback (most recent call last):
  File "/home/labex/project/main.py", line 7, in <module>
    calc = Calculator()
NameError: name 'Calculator' is not defined

Эта ошибка подтверждает, что в текущее пространство имен попадают только те объекты, которые указаны в операторе from...import. Этот метод может сделать ваш код более читаемым, но также увеличивает риск конфликтов имен, если вы импортируете объекты с одинаковыми именами из разных модулей.

Прежде чем переходить к следующему шагу, удалите две строки, которые вызвали ошибку, из main.py.

Понимание и использование пакетов Python

По мере роста проектов вы можете захотеть организовать связанные модули в единую иерархию каталогов. Для этого и существуют пакеты (packages). Пакет — это каталог, содержащий специальный файл с именем __init__.py (который может быть пустым). Наличие этого файла указывает Python рассматривать каталог как пакет.

Давайте создадим пакет для размещения нашего module_a.

Сначала создайте новый каталог с именем my_package в каталоге ~/project. Вы можете сделать это, щелкнув правой кнопкой мыши в проводнике файлов и выбрав "Новая папка".

mkdir my_package

Затем создайте необходимый файл __init__.py внутри нового каталога my_package.

touch my_package/__init__.py

Теперь переместите module_a.py в каталог my_package. Вы можете перетащить файл в проводнике файлов.

mv module_a.py my_package/

Структура вашего проекта теперь должна выглядеть следующим образом:

~/project/
├── main.py
├── hello.py
└── my_package/
    ├── __init__.py
    └── module_a.py

При такой структуре пакета нам необходимо обновить способ импорта module_a в нашем скрипте main.py. Для импорта модуля из пакета вы используете имена модулей с точками, например package_name.module_name.

Откройте main.py и измените его, чтобы импортировать функцию greet из my_package.module_a:

from my_package.module_a import greet

greet("Package")

Сохраните файл и запустите его:

python3 main.py

Вы должны увидеть следующий вывод:

Hello, Package from module_a!

Это показывает, как импортировать конкретный объект из модуля внутри пакета. Альтернативно, вы могли бы импортировать сам модуль:

## Alternative import style
import my_package.module_a

my_package.module_a.greet("Alternative")

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

Резюме

В этой лабораторной работе вы изучили основные концепции организации кода в Python. Вы начали с понимания того, что такое модуль, и цели блока if __name__ == "__main__": для создания повторно используемого кода. Затем вы практиковались в импорте модулей с использованием синтаксиса import module_name и доступе к их членам с помощью точечной нотации.

Кроме того, вы изучили оператор from...import для непосредственного внесения определенных объектов из модуля в пространство имен вашего скрипта. Наконец, вы узнали, как структурировать связанные модули в пакет, создав каталог с файлом __init__.py, и как выполнять импорт из этого пакета. Эти навыки являются основополагающими для написания чистого, организованного и масштабируемого кода на Python.