Рубрики
Без рубрики

Относительный и абсолютный импорт в Python

Автор оригинала: Guest Contributor.

Относительный и абсолютный импорт в Python

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

Что такое Импорт?

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

Например, Python дал бы NameError для следующего кода:

myPi = math.pi

Это происходит потому, что ни объект math , ни его свойства и методы изначально не доступны самому языку. Чтобы использовать объект math , вы должны сначала импортировать его.

import math

myPi = math.pi
print myPi

Оператор import добавляет объект в текущую область действия вашей программы.

Как Работает Импорт

Операторы import многое делают под капотом для импорта файла или модуля. Во-первых, они ищут ваш модуль или пакет в sys.modules , где Python хранит ваш ранее импортированный код. Если Python не может найти там модуль, он будет искать его в стандартной библиотеке Python . Если Python все еще не может найти модуль, он будет проходить через все ваше пространство хранения, начиная с текущего каталога и тех, которые перечислены в вашем system.path . Если модуль найден в этих местах, он добавит модуль в вашу программу, в противном случае он даст ModuleNotFoundError .

Синтаксис инструкции импорта

Чтобы импортировать модуль напрямую, вы просто ставите имя модуля или пакета после ключевого слова import . Обратите внимание, что это заявление чувствительно к регистру.

import mymodule

Однако Python предлагает более сложный синтаксис для импорта кода. Этот второй формат также включает ключевое слово from .

from mypackage import mymodule

В этом формате вы указываете как модуль или код , который вы хотите, так и где он находится . Вы вводите имя своего кода, модуля или подпакета для my module и его местоположение для my package . Такой оператор импорта отлично подходит, если вы хотите импортировать только часть кода из упомянутого пакета, а не сам пакет.

Вы даже можете переименовать модуль, включив ключевое слово as .

import mymodule as oMyFunction

Вы также можете использовать звездочку ( * ) в качестве джокера. Следующая инструкция импортирует все функции и свойства, содержащиеся в пакете math .

from math import *

Независимо от синтаксиса, вы всегда должны следовать рекомендациям importing best practices .

Абсолютный импорт

Абсолютный импорт включает в себя весь путь к вашему скрипту, начиная с корневой папки программы. Хотя вы должны отделить каждую папку точкой, вы можете иметь ее столько, сколько вам нужно.

Ниже приведены примеры абсолютного импорта:

from package1.firstmodule import firstmodule
import package1.secondmodule.myfunction
Абсолютные преимущества и недостатки импорта

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

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

Вы также можете обнаружить проблему при запуске программы с использованием различных загрузочных файлов. Интерпретатор Python объявляет текущую папку исходного файла только как его sys.path package root. Это нормально, если вы загружаете свою программу только с помощью файлов из корневой папки. Это происходит потому, что sys.path будет оставаться статичным на протяжении всего вашего скрипта.

Однако ситуация меняется, когда вы запускаете свою программу из подпапки или в любой другой ситуации, когда ваш sys.path может измениться. Тогда ваша “корневая папка” – это подпапка. Поскольку вы не можете использовать неявный импорт (как мы увидим ниже), любой файл вне подпапки становится недоступным для вашей программы.

У вас есть два обходных пути для этого. Вы можете либо запустить скрипт вложенной папки как импортированный модуль, либо добавить sys.path непосредственно в свой код.

Например:

  • Импорт модулей во время выполнения: python-m package.a 2
  • Добавьте sys.path перед импортом файлов:
import os, sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
from packA.subA import sa2

Относительный Импорт

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

Что касается синтаксиса, то относительный импорт использует точечную нотацию . Одиночные точки представляют каталог текущего скрипта. Две точки представляют родительскую папку. Три точки означают бабушку и дедушку, и так далее. Вы можете быть знакомы с этой системой, если используете UNIX-подобную операционную систему или консоль Windows.

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

    Явный импорт
import other
from . import some_class
from .subA import sa1
    Неявный импорт
from .some_module import some_class
import some_function
import subA.sa1
Относительный импорт и его преимущества и недостатки

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

from ..my_sub_package.my_module import my_function

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

Какой импорт использовать?

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

Вывод

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

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