Файл modu.py, находящийся в каталоге pack/, импортируется с помощью выражения import pack.modu. Интерпретатор выполнит поиск файла __init__.py в pack и запустит все его выражения верхнего уровня. Затем выполнит поиск файла с именем pack/modu.py и запустит все его выражения верхнего уровня. После этих операций любая переменная, функция или класс, определенные в файле modu.py, будут доступны пространству имен pack.modu.
Распространенная проблема заключается в том, что файлы __init__.py содержат слишком много кода. Когда сложность проекта повышается, в структуре каталогов могут появляться подпакеты и подподпакеты. В этом случае импортирование одного элемента из подподпакета потребует запуска всех файлов __init__.py, встреченных в дереве на пути к искомому.
Признаком хорошего тона является поддержание файла __init__.py пустым, когда модули и подпакеты пакета не имеют общего кода. Проекты HowDoI и Diamond, использованные в качестве примеров в следующем разделе, не содержат кода в файлах __init__.py, помимо номеров версий. В проектах Tablib, Requests и Flask в этом файле есть строка документации верхнего уровня и выражения импорта, предоставляющие API каждого проекта. Проект Werkzeug также предоставляет API верхнего уровня, но делает это с помощью ленивой загрузки (дополнительного кода, который добавляет содержимое в пространство имен, только когда тот используется, что ускоряет работу исходного выражения импорта).
Наконец, для импортирования глубоких вложенных пакетов доступен удобный синтаксис: import very.deep.module as mod. Это позволяет использовать слово mod на месте избыточной конструкции very.deep.module.
Объектно-ориентированное программирование
Python иногда описывается как объектно-ориентированный язык. Это может вносить путаницу, поэтому давайте проясним данный вопрос.
В Python все элементы являются объектами и могут быть обработаны как объекты. Именно это мы имеем в виду, когда говорим, что функции являются объектами первого класса. Функции, классы, строки и даже типы считаются в Python объектами: все они имеют тип, их можно передать как аргументы функций, они могут иметь методы и свойства. С этой точки зрения Python действительно объектно-ориентированный язык.
Однако, в отличие от Java, в Python парадигма объектно-ориентированного программирования не будет основной. Проект, написанный на Python, вполне может быть не объектно-ориентированным, то есть в нем не будут использоваться (или будут, но в небольших количествах) определения классов, наследование классов или другие механизмы, характерные для объектно-ориентированного программирования. Для питонистов эта функциональность
Защитники функционального программирования (парадигма, которая в своей чистейшей форме не имеет операторов присваивания и побочных эффектов и вызывает функции одну за другой, чтобы выполнить задачу) могут утверждать: из-за того, что функция выполняет разную работу в зависимости от состояния системы (например, от глобальной переменной, которая указывает, вошел ли пользователь под своей учетной записью), могут возникать ошибки и путаница. В Python (несмотря на то что он не является чисто функциональным языком) имеются инструменты, которые позволяют заниматься функциональным программированием (http://bit.ly/functional-programming-python). Мы можем ограничить применение пользовательских классов до ситуаций, когда понадобится объединить состояние и функциональность.
В некоторых архитектурах, обычно в веб-приложениях, создается несколько процессов Python для того, чтобы реагировать на внешние запросы, которые могут происходить одновременно. В этом случае сохранение состояния созданных объектов (означает хранение статичной информации о мире) может привести к
Например, запрос может загрузить предмет в память и затем пометить, что он добавлен в корзину пользователя. Если другой запрос в то же время «продаст» такой же предмет другому человеку, может случиться, что продажа на самом деле произойдет после того, как первая сессия добавит предмет (затем мы попытаемся продать предмет, который уже помечен как проданный). Подобные проблемы приводят к тому, что многие предпочитают функции, не сохраняющие состояние.