Автор оригинала: 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, включая абсолютный и относительный импорт. Мы также сравнили плюсы и минусы каждого из них, которые имеют свои преимущества в разных случаях использования.