Модули и пакеты
Модули, пакеты, импорт и организация кода.
5 вопросов
JuniorТеорияОчень частоЧто такое __name__, и когда он равен "__main__"?
Что такое __name__, и когда он равен "__main__"?
У каждого модуля есть __name__. При импорте __name__ содержит имя модуля. При прямом запуске файла как скрипта Python присваивает __name__ значение "__main__", что включает блок if __name__ == "__main__":.
Типичные ошибки
- ✗Считать, что
__name__всегда"__main__", и потому защита срабатывает и при импорте - ✗Думать, что
__name__всегда равен имени файла независимо от способа запуска - ✗Класть стартовый код вне блока
if __name__ == "__main__":, и он исполняется при импорте
Уточняющие вопросы
- →Какое значение у
__name__внутри модуля, импортированного какpackage.item? - →Почему блок
if __name__ == "__main__":считается хорошей практикой?
JuniorТеорияЧастоЧто такое module в Python?
Что такое module в Python?
Module — это один файл .py с кодом, переиспользуемая единица, подключаемая через import. Первый import исполняет файл один раз и связывает его имена в объекте модуля. Модули группируют код и собираются в пакеты.
Типичные ошибки
- ✗Думать, что каждый
importзаново исполняет файл — он выполняется один раз, затем кэшируется - ✗Считать, что module обязан быть директорией, а не одним файлом
.py - ✗Путать module (один файл
.py) с пакетом (директорией из модулей)
Уточняющие вопросы
- →Где Python кэширует уже импортированные модули, чтобы файл исполнялся лишь раз?
- →Чем файл
.pyотличается от директории-пакета с__init__.py?
JuniorТеорияЧастоЧто такое пакет, и что делает директорию пакетом?
Что такое пакет, и что делает директорию пакетом?
Пакет — это директория, группирующая модули как пространство имён. Обычный пакет содержит __init__.py, который исполняется при импорте и может быть пустым. Каждый пакет — module, но не наоборот.
Типичные ошибки
- ✗Считать любую директорию пакетом без файла-маркера
__init__.py - ✗Думать, что пакет сам по себе не module, поэтому импорт одного имени пакета ничего не делает
- ✗Думать, что
__init__.pyобязан содержать код, хотя он может быть пустым
Уточняющие вопросы
- →Что и когда исполняется при первом импорте
package.item? - →Чем обычный пакет отличается от namespace-пакета?
MiddleТеорияИногдаКак Python находит module, когда вы делаете import?
Как Python находит module, когда вы делаете import?
Python просматривает sys.path по порядку: каталог скрипта (или cwd), затем записи из PYTHONPATH, затем пути стандартной библиотеки. sys.path — изменяемый список, и побеждает первое найденное совпадение.
Типичные ошибки
- ✗Считать, что Python сканирует всю файловую систему, а не только
sys.path - ✗Думать, что
sys.pathнеизменяем, хотя это изменяемый список, который можно править - ✗Забывать, что побеждает первое совпадение в
sys.path, и порядок затеняет поздние записи
Уточняющие вопросы
- →Как добавить директорию в
sys.pathво время выполнения, и когда это рискованно? - →Что такое затенение модулей, и как порядок в
sys.pathего вызывает?
SeniorТеорияРедкоЧто такое namespace-пакет, и чем он отличается от обычного?
Что такое namespace-пакет, и чем он отличается от обычного?
Namespace-пакет (PEP 420, Python 3.3+) — это пакет БЕЗ __init__.py. Он может быть разбит на НЕСКОЛЬКО директорий в sys.path, которые Python сливает в один логический пакет. Обычный пакет имеет __init__.py в одной директории.
Типичные ошибки
- ✗Считать, что каждому пакету всегда нужен
__init__.py, даже namespace-пакету - ✗Думать, что namespace-пакет не может охватывать несколько директорий в
sys.path - ✗Путать обычный пакет (одна директория, есть
__init__.py) с namespace-пакетом
Уточняющие вопросы
- →Как Python сливает две директории с одним именем пакета в
sys.path? - →Когда разбиение одного пакета на отдельно устанавливаемые дистрибутивы полезно?