Хотя вы можете поместить простые проекты в один файл, для большинства проектов разработки Python потребуется несколько файлов, чтобы ими можно было управлять. Это означает, что вам нужен способ импортировать один файл в другой. Однако многие питонисты находят импорт файлов запутанным.
Импорт означает предоставление файлу или модулю Python доступа к скрипту из другого файла или модуля. Вы можете использовать только функции и свойства, к которым имеет доступ ваша программа. Например, если вы хотите использовать математические функции, вы должны сначала импортировать пакет math. Это потому, что вы должны определить все, что хотите использовать в Python, прежде чем использовать их.
Например, Python выдаст NameError для следующего кода:
myPi = math.pi
Это связано с тем, что ни математический объект, ни его свойства и методы изначально не доступны для самого языка. Чтобы использовать математический объект, вы должны сначала импортировать его.
import math myPi = math.pi print myPi
Оператор import добавляет объект в текущую область вашей программы.
Как работает import?
Оператор import многое делает для импорта файла или модуля. Во-первых, они ищут ваш модуль или пакет в sys.modules, где Python хранит ваш ранее импортированный код. Если Python не может найти там модуль, он будет искать его в стандартной библиотеке.
Если Python по-прежнему не может найти модуль, он пройдется по всему пространству вашего хранилища, начиная с текущего каталога и тех, которые перечислены в вашем system.path. Если модуль находится в этих местах, он добавит модуль в вашу программу, в противном случае он выдаст ModuleNotFoundError.
Синтаксис оператора импорта
Чтобы импортировать модуль напрямую, вы просто указываете имя модуля или пакета после ключевого слова import. Обратите внимание, что это утверждение чувствительно к регистру.
import mymodule
Однако Python предлагает более сложный синтаксис для импорта кода. Этот второй формат также включает ключевое слово from.
from mypackage import mymodule
В этом формате вы указываете и модуль, или код, который хотите, вместе с тем, где он находится. Вы указываете имя своего кода, модуля или подпакета для mymodule и его расположение для mypackage. Такой оператор import хорош, если вы хотите импортировать только часть кода из упомянутого пакета, а не сам пакет.
Вы даже можете переименовать модуль, включив ключевое слово as.
import mymodule as oMyFunction
Вы также можете использовать звездочку (*), как подстановочный знак. Следующий оператор импортирует все функции и свойства, содержащиеся в математическом пакете.
from math import *
Независимо от синтаксиса, вы всегда должны следовать рекомендуемым передовым методам импорта.
Абсолютный импорт
Абсолютный импорт включает полный путь к вашему скрипту, начиная с корневой папки программы. Вы должны разделять каждую папку точкой.
Ниже приведены примеры абсолютного импорта:
from package1.firstmodule import firstmodule import package1.secondmodule.myfunction
Преимущества и недостатки
В отличие от других языков, большинство разработчиков Python предпочитают использовать абсолютный импорт. Это потому, что абсолютный импорт действительно ясно показывает, что вы пытаетесь сделать. Фактическое расположение ваших файлов прямо в вашем коде. Фактически, вы можете использовать их в любом месте вашего кода.
Однако абсолютный импорт может длиться довольно долго. Если в вашем проекте есть подпакеты, ваши операторы импорта могут выходить за рамки одной строки кода. Когда это произойдет, вам будет гораздо лучше использовать относительный импорт.
Вы также можете обнаружить проблему при запуске программы с использованием других файлов. Интерпретатор Python только объявляет текущую папку начального файла, как корень своего пакета sys.path. Это нормально, если вы загружаете свою программу только с использованием файлов из корневой папки. Это связано с тем, что sys.path будет оставаться статическим на протяжении всего скрипта.
Однако ситуация меняется, когда вы запускаете свою программу из подпапки или в любой другой ситуации, когда ваш sys.path может измениться. Тогда ваша «корневая папка» будет подпапкой. Поскольку вы не можете использовать неявный импорт (как мы увидим ниже), любой файл вне подпапки становится недоступным для вашей программы.
У вас есть два обходных пути. Вы можете запустить скрипт подпапки, как импортированный модуль или добавить sys.path прямо в код.
Например:
- Импорт модулей, как время выполнения: python -m packA.a2.
- Добавьте 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.
Ниже приведены примеры относительного импорта:
- 1. Явный импорт:
import other from . import some_class from .subA import sa1
- 2. Неявный импорт:
from .some_module import some_class import some_function import subA.sa1
Преимущества и недостатки
Относительный импорт редко растет до тех пор, пока абсолютный импорт не растет. Они даже могут превратить длинное абсолютное утверждение в нечто простое, например:
from ..my_sub_package.my_module import my_function
Однако они также скрывают пути к вашим модулям. Это может быть нормально, если вы единственный разработчик, но это становится беспорядочным, если вы являетесь частью команды разработчиков, где фактическая структура каталогов может измениться.
Какой импорт использовать?
Если вы не работаете над большим проектом с несколькими уровнями подпакетов, вы всегда должны использовать абсолютный импорт.
Таким образом, ваш код будет легко понят для всех, включая вас самих, если вы вернетесь к нему, чтобы обновить его позже. Даже если у вас есть длинные пути, вы все равно должны попытаться написать свою программу, чтобы использовать только абсолютные операторы, чтобы упростить ваш код.
Заключение
Как и любой другой современный язык программирования, Python позволяет импортировать код из других файлов или модулей. Однако это может обернуться запутанным и подверженным ошибкам процессом, если вы не понимаете концепции, лежащие в основе системы импорта.
В этой статье мы рассмотрели различные способы импорта кода в наши программы Python, включая абсолютный и относительный импорт. Мы также сравнили плюсы и минусы каждого из них, которые имеют свои преимущества в разных скриптах использования.