Система импорта в Python
Оператор import является наиболее распространенным способом вызова определений модуля, но это не единственный способ. Такие функции, как importlib.import_module() и встроенная функция __import__() также могут быть использованы для вызова механизма импорта.
Оператор import объединяет две операции: он выполняет поиск именованного модуля, а затем привязывает результаты этого поиска к имени в области видимости вызывающей стороны. Операция поиска оператором import определяется как вызов функции __import__() с соответствующими аргументами. Возвращаемое значение __import__() используется для выполнения операции связывания имени оператором import .
Прямой вызов функции __import__() выполняет только поиск модуля и, если он найден, операцию инициализации модуля. Только оператор import выполняет операцию привязки имени к пространству имен вызывающей стороны.
При первом импорте модуля Python выполняет поиск модуля и, если он найден, создает объект модуля, инициализируя его. Если именованный модуль не может быть найден, то вызывается исключение ModuleNotFoundError .
importlib
Модуль importlib предоставляет богатый API для взаимодействия с системой импорта. Например, importlib.import_module() предоставляет рекомендуемый, более простой API, чем встроенный __import__() , для вызова механизма импорта.
Спецификация инструкции import
Базовая инструкция `import`, без оператора `from`, выполняется в два этапа. Поиск модуля, загрузка и инициализация его при необходимости. Определение имени или имён, в локальном пространстве имен, для области, в которой выполняется инструкция import.
Определение модуля и его импорт в Python
Модуль — это файл, содержащий определения и операторы Python. Имя файла — это имя модуля с добавленным суффиксом `.py`. Внутри модуля, имя модуля, в виде строки, доступно в качестве значения глобальной переменной `__name__`.
Конструкция импорта import modulle as name
Содержимое модуля можно импортировать из определения функции. В этом случае импорт не выполняется до тех пор, пока не будет вызвана функция
Конструкция импорта from modulle import names
Альтернативная форма инструкции `import` позволяет импортировать отдельные объекты из модуля непосредственно в область видимости вызывающего объекта (другого модуля или скрипта)
Конструкция импорта from modulle import name as alt_name
Можно импортировать отдельные объекты модуля, но ввести их в глобальную область видимости скрипта с альтернативными именами
Как Python ищет импортируемый модуль
Каталог, из которого был запущен скрипт. Список каталогов, содержащихся в переменной окружения `PYTHONPATH`. Список каталогов, настроенных во время установки Python.
Список имен, определенных в модуле Python
Встроенная функция `dir()` возвращает список определенных имен в пространстве имен. Если задан аргумент, который является именем модуля, `dir()` перечисляет имена, определенные в модуле.
Выполнение модуля как скрипта
Когда файл `.py` импортируется как модуль, Python устанавливает специальную переменную `__name__` в имя модуля. Однако, если файл выполняется как автономный сценарий, `__name__` устанавливается в строку `__main__`.
Перезагрузка модуля в Python
Если в модуль вносятся изменения то его нужно перезагружать, что бы изменения вступили в силу. Для этого нужно либо перезапустить интерпретатор, либо использовать функцию `importlib.reload()` из модуля `importlib`
Пакеты модулей в Python
Пакеты позволяют иерархически структурировать пространство имен модуля с использованием точечной нотации. Точно так же, как модули помогают избежать коллизий между именами глобальных переменных, пакеты помогают избежать коллизий между именами модулей
Файл пакета __init__.py
Если файл с именем __init__.py присутствует в каталоге пакета, то он вызывается при импорте пакета или модуля в пакете. Это может быть использовано для выполнения кода инициализации пакета, например инициализации данных уровня пакета.
Переменная __all__ в пакетах и модулях в Python
Если `__init__.py` файл в каталоге пакета содержит список с именем `__all__`, он считается списком модулей, которые должны быть импортированы при обнаружении инструкции `from import *`.
Переменная пакета __path__ в Python
Атрибут пакета `__path__` используется при импорте его подпакетов. В механизме импорта он работает почти так же, как `sys.path` и предоставление списка местоположений для поиска модулей во время импорта.
Относительный импорт пакетов
Относительный импорт использует опережающие точки.
Вложенные подпакеты
Пакеты могут содержать вложенные подпакеты произвольной глубины. Для отделения имени пакета от имени вложенного пакета используется дополнительная точечная нотация
Пространства имен пакета
В настоящее время Python предоставляет pkgutil.extend_path для обозначения пространства имен пакета. `setuptools` предоставляет аналогичную функцию с именем `pkg_resources.declare_namespace`.
Настройка доступа к атрибутам модуля в Python
Специальные имена __getattr__ и __dir__ также могут использоваться для настройки доступа к атрибутам модуля. Функция __getattr__ на уровне модуля должна принимать один аргумент, который является именем атрибута, и возвращать вычисленное значение или вызывать AttributeError.
Как работают импорты в Python
Импорты не так просты, как кажется. Тем более если они пишутся для двух несовместимых версий языка. Разбираемся с основными проблемами и их решением.
Порой бывает трудно правильно реализовать import с первого раза, особенно если мы хотим добиться правильной работы на плохо совместимых между собой версиях Python 2 и Python 3. Попытаемся разобраться, что из себя представляют импорты в Python и как написать решение, которое подойдёт под обе версии языка.
Ключевые моменты
- Выражения import производят поиск по списку путей в sys.path .
- sys.path всегда включает в себя путь скрипта, запущенного из командной строки, и не зависит от текущей рабочей директории.
- Импортирование пакета по сути равноценно импортированию __init__.py этого пакета.
Основные определения
- Модуль: любой файл *.py . Имя модуля — имя этого файла.
- Встроенный модуль: «модуль», который был написан на Си, скомпилирован и встроен в интерпретатор Python, и потому не имеет файла *.py .
- Пакет: любая папка, которая содержит файл __init__.py . Имя пакета — имя папки.С версии Python 3.3 любая папка (даже без __init__.py) считается пакетом.
- Объект: в Python почти всё является объектом — функции, классы, переменные и т. д.
Пример структуры директорий
test/ # Корневая папка packA/ # Пакет packA subA/ # Подпакет subA __init__.py sa1.py sa2.py __init__.py a1.py a2.py packB/ # Пакет packB (неявный пакет пространства имён) b1.py b2.py math.py random.py other.py start.py
Обратите внимание, что в корневой папке test/ нет файла __init__.py .
Что делает import
При импорте модуля Python выполняет весь код в нём. При импорте пакета Python выполняет код в файле пакета __init__.py , если такой имеется. Все объекты, определённые в модуле или __init__.py , становятся доступны импортирующему.
Основы import и sys.path
Вот как оператор import производит поиск нужного модуля или пакета согласно документации Python:
-
t
- директории, содержащей исходный скрипт (или текущей директории, если файл не указан); t
- директории по умолчанию, которая зависит от дистрибутива Python; t
- PYTHONPATH (список имён директорий; имеет синтаксис, аналогичный переменной окружения PATH ).
Технически документация не совсем полна. Интерпретатор будет искать не только файл (модуль) spam.py , но и папку (пакет) spam .
Обратите внимание, что Python сначала производит поиск среди встроенных модулей — тех, которые встроены непосредственно в интерпретатор. Список встроенных модулей зависит от дистрибутива Python, а найти этот список можно в sys.builtin_module_names (Python 2 и Python 3). Обычно в дистрибутивах есть модули sys (всегда включён в дистрибутив), math , itertools , time и прочие.
В отличие от встроенных модулей, которые при поиске проверяются первыми, остальные (не встроенные) модули стандартной библиотеки проверяются после директории запущенного скрипта. Это приводит к сбивающему с толку поведению: возможно «заменить» некоторые, но не все модули стандартной библиотеки. Допустим, модуль math является встроенным модулем, а random — нет. Таким образом, import math в start.py импортирует модуль из стандартной библиотеки, а не наш файл math.py из той же директории. В то же время, import random в start.py импортирует наш файл random.py .
Кроме того, импорты в Python регистрозависимы: import Spam и import spam — разные вещи.
Функцию pkgutil.iter_modules() (Python 2 и Python 3) можно использовать, чтобы получить список всех модулей, которые можно импортировать из заданного пути:
import pkgutil search_path = ['.'] # Используйте None, чтобы увидеть все модули, импортируемые из sys.path all_modules = [x[1] for x in pkgutil.iter_modules(path=search_path)] print(all_modules)
Чуть подробнее о sys.path
Чтобы увидеть содержимое sys.path , запустите этот код:
import sys print(sys.path)
Документация Python описывает sys.path так:
Список строк, указывающих пути для поиска модулей. Инициализируется из переменной окружения PYTHONPATH и директории по умолчанию, которая зависит от дистрибутива Python.При запуске программы после инициализации первым элементом этого списка, path[0] , будет директория, содержащая скрипт, который был использован для вызова интерпретатора Python. Если директория скрипта недоступна (например, если интерпретатор был вызван в интерактивном режиме или скрипт считывается из стандартного ввода), то path[0] является пустой строкой. Из-за этого Python сначала ищет модули в текущей директории. Обратите внимание, что директория скрипта вставляется перед путями, взятыми из PYTHONPATH .Источник: Python 2 и Python 3
Документация к интерфейсу командной строки Python добавляет информацию о запуске скриптов из командной строки. В частности, при запуске python .py .
Если имя скрипта ссылается непосредственно на Python-файл, то директория, содержащая этот файл, добавляется в начало sys.path , а файл выполняется как модуль main .Источник: Python 2 и Python 3
Итак, повторим порядок, согласно которому Python ищет импортируемые модули:
- Модули стандартной библиотеки (например, math , os ).
- Модули или пакеты, указанные в sys.path :Если интерпретатор Python запущен в интерактивном режиме:sys.path[0] — пустая строка ». Это значит, что Python будет искать в текущей рабочей директории, из которой вы запустили интерпретатор. В Unix-системах эту директорию можно узнать с помощью команды pwd.Если мы запускаем скрипт командой python
Импорт файлов и модулей в Python
В Python импорт файлов и модулей является одной из основных операций, которая позволяет использовать код одного файла в другом. Эта возможность позволяет создавать модульные и многокомпонентные приложения, где каждый файл или модуль выполняет свою специфическую задачу.
Импорт файла
Допустим, есть файл file.py , который содержит некоторый код, который нужно использовать в другом файле. Для этого используется оператор import . В другом файле Python достаточно просто написать import file (без расширения .py), и код из file.py станет доступен.
Импорт папки
Для импорта всей папки (которая в Python называется пакетом) используется тот же оператор import , но с добавлением точки и имени файла. Если, например, в папке folder есть файл file.py , то его можно импортировать следующим образом: import folder.file .
Динамический импорт
Динамический импорт позволяет загружать модули на основе пользовательского ввода. Для этого используется функция __import__() или модуль importlib . Например, если имя модуля хранится в переменной module_name , то его можно импортировать следующим образом: __import__(module_name) .
Импорт части файла
Иногда нужно импортировать не весь файл, а только определенную его часть, например, одну функцию. Для этого используется оператор from . import . . Если, например, в файле file.py есть функция function , то ее можно импортировать следующим образом: from file import function .
Все эти способы позволяют гибко управлять импортом файлов и модулей в Python, делая код более структурированным и модульным.
Урок 5.
Модули и пакеты в Python. Импорт. Виртуальная среда venv.
Рассматриваем модули и пакеты из стандартной библиотеки Python и PyPI. Учимся использовать инструкции import и from..import и различать абсолютный и относительный импорт. Разбираемся с виртуальными пространствами venv. Создаем собственные модули.

Курс «Программирование на Python»
Урок 5.
Модули и пакеты в Python. Импорт. Виртуальная среда venv.
Рассматриваем модули и пакеты из стандартной библиотеки Python и PyPI. Учимся использовать инструкции import и from..import и различать абсолютный и относительный импорт. Разбираемся с виртуальными пространствами venv. Создаем собственные модули.
Предыдущий урок
Урок 4. Работа со строками
Следующий урок
Урок 6. Принципы ООП. Классы, объекты, поля и методы. Уровни доступа.
ТЕОРЕТИЧЕСКИЙ БЛОК
В КОНЦЕ УРОКА ЕСТЬ ВИДЕО

Модуль (Module) в Python
Программы на Python содержат тысячи, десятки тысяч и сотни тысяч строк кода (есть проекты с миллионами). В таких условиях одним файлом с кодом не обойдёшься — его нужно разбивать на части. И с целью получения доступа к коду, который находится в других файлах, в Python реализован механизм модулей.
Что такое модуль в терминологии Python? Официальная документация дает следующее определение:

Module — an object that serves as an organizational unit of Python code. Modules have a namespace containing arbitrary Python objects. Modules are loaded into Python by the process of importing.
Иными словами, модуль(module) в Python — это просто файл, содержащий код на Python. Каждый модуль может содержать переменные, классы и функции. Кроме того, в модуле может находиться исполняемый код. Имя модуля соответствует имени файла. Например:
# Имя файла math.py # Имя модуля math
Каждая программа может импортировать модуль и получить доступ к его классам, функциям и объектам. Нужно заметить, что модуль может быть написан не только на Python(обычные модули), а например, на C или C++(модули расширения).
- Имеет расширение *.py (имя файла без расширения является именем модуля).
- Может быть импортирован.
- Может быть многократно использован.
- Позволяет вам логически организовать ваш код на Python.

Пакет (Package) в Python
Идем дальше. Если начать делить код достаточно большого проекта на модули, то довольно быстро может возникнуть желание сгруппировать несколько близких по тематике модулей. Или же мы захотим вынести часть модулей из проекта, чтобы их можно было использовать в других проектах. И тут нам на помощь приходят пакеты(packages) в Python, которые служат для объединения модулей в группы.
Вот что на эту тему говорит документация Python:

Package — a Python module which can contain submodules or recursively, subpackages.
Пакет — это набор взаимосвязанных модулей(при этом стоит уточнить, что сам пакет тоже является модулем), предназначенных для решения задач определенного класса некоторой предметной области. Это такой способ структуризации модулей. Пакет представляет собой папку, в которой содержатся модули и другие пакеты и обязательный файл __init__.py , отвечающий за инициализацию пакета.
На самом деле
Некоторые пакеты Python не содержат файл __init__.py . Это так называемые namespace package s, которые служат просто как контейнеры подпакетов. Однако мы не станем на них подробно останавливаться, просто будем иметь ввиду, что такие пакеты существуют. Подробнее можно почитать в PEP 420.
Пример содержимого каталога стандартного пакета json , который, как можно заметить, состоит из 4 модулей и файла __init__.py :
json/ ├── __init__.py ├── decoder.py ├── encoder.py ├── scanner.py └── tool.py
- Именем пакета является название данного каталога.
- С версии Python 3.3 любая папка (даже без __init__.py ) считается пакетом.
- Пакет может быть импортирован(так же как и модуль).
- Пакет может быть многократно использован(так же как и модуль).

Классификация модулей
- Стандартная библиотека Python (англ. Standard Library).
- Сторонние модули (англ. 3rd Party Modules)
- Пользовательские модули

Python. Классификация модулей.
Поговорим о каждой из групп немного подробнее — расскажем, где найти модули в каждом случае, и приведем примеры самых популярных и полезных из них.
1. Стандартная библиотека Python
- Встроенные модули. Входят в состав интерпретатора и написаны на языке С, что позволяет им обеспечивать эффективный доступ к функциональности на уровне ОС — например, к системе ввода-вывода данных. Многие из встроенных модулей являются платформозависимыми. Например, модуль winreg , предназначенный для работы с реестром ОС Windows, устанавливается только на соответствующей ОС.
- Модули расширения. Написаны на Python. Представляют собой стандартные способы решения наиболее часто встречающихся задач программирования. Сюда входят модули для работы со многими сетевыми протоколами и форматами интернета, регулярными выражениями, текстовыми кодировками, мультимедийными форматами, криптографическими протоколами, архивами, а также для сериализации данных, поддержки юнит-тестирования и др.
Библиотека;Описание
sys; Обеспечивает доступ к некоторым переменным и функциям, взаимодействующим с интерпретатором Python, например — доступ к аргументам командной строки, списку встроенных модулей Python, текущим исключениям, информации об операционной системе. os; Предоставляет множество функций для работы с операционной системой. Например, получение версии и другой информации о текущей ОС, работа с переменными окружения и файловой системой. os.path; Является вложенным в модуль os(по сути os является пакетом), и реализует некоторые полезные функции для работы с файлами — доступ к характеристикам файла и манипуляции с путями. time, datetime; Данные модули предоставляют классы для обработки времени и даты разными способами. random; Предоставляет функции для генерации случайных чисел, букв, случайного выбора элементов последовательности. collections;Предоставляет специализированные типы данных — счетчики, очереди, упорядоченные словари. json; Позволяет кодировать и декодировать данные в формате JSON. unittest; Предоставляет богатый набор инструментов для написания и запуска автоматизированных тестов. re;Модуль re используется для работы с регулярными выражениями. hashlib;Предназначен для шифрования строк. bz2, gzip, tarfile, zipfile;Данные модули созданы для архивации/распаковки данных в разных форматах.
2. Сторонние модули (англ. 3rd Party Modules)
Это модули и пакеты, которые не входят в дистрибутив Python и могут быть установлены из каталога пакетов Python с помощью пакетного менеджера (например, pip или easy_install ).
PyPI (Python Package Index) — главный каталог библиотек на Python. Содержит более 200 000 пакетов.
Приведем несколько примеров популярных пакетов из каталога PyPI.
Библиотека;Описание
six;Библиотека совместимости Python 2 и 3. Содержит функции, сглаживающие различия в версиях Python. urllib3;HTTP клиент для Python requests;HTTP клиент для Python. Технически является более удобной оберткой над urllib3. python-dateutil; Расширяет функционал по работе со временем и датой относительно модуля datetime из Стандартной библиотеки Python. docutils;Библиотека-процессор для документов написанных с помощью разметки ReST. pyyaml;YAML парсер/генератор awscli;Предоставляет интерфейс командной строки для Amazon Web Services numpy;Пакет для вычислений с многомерными массивами. Его можно рассматривать как свободную альтернативу MATLAB. pytest;Библиотека для создания и запуска автоматизированных unit тестов(альтернатива unittest) flask;Фреймворк для создания веб-приложений на Python
3. Пользовательские (собственные) модули
Python предоставляет возможность создания собственных модулей. Для создания таких модулей нет особенных правил — любой файл с расширением *.py является модулем, а создается, как правило, разработчиком для собственных нужд. В подавляющем большинстве случае такой пакет или модуль не размещается в каталоге пакетов Python.
