6.1. Подробнее о модулях

Наряду с определениями функций модули могут содержать исполняемые операторы. Эти операторы предназначены для инициализации модуля. Они выполняются только однажды, когда в операторе импорта встречается имя модуля. (Они также запускаются, если файл выполняется как скрипт.)

(На самом деле определения функций также "операторы", которые "выполняются"; выполнение определения функции уровня модуля вводит имя функции в глобальную таблицу символов модуля.)

Каждый модуль имеет его собственную приватную таблицу символов, которая используется как глобальная таблица символов всеми функциями, определенными в модуле. Поэтому разработчик модуля может использовать глобальную переменную в модуле без беспокойства о случайном конфликте с глобальной переменной пользователя. С другой стороны, если вы знаете, что делаете, то можете использовать глобальную переменную модуля с такой же нотацией, которая используется для ссылки на его функцию, modname.itemname.

Модули могут импортировать другие модули. Принято, но не является необходимым, размещать все операторы import в начале модуля (это касается и скрипта). Имя импортируемого модуля помещается в глобальную таблицу символов импортирующего модуля.

Существует вариант оператора import, который импортирует имена из модуля прямо в таблицу символов импортирующего модуля. Например:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Это не вводит имя модуля, из которого осуществляется импорт, в локальную таблицу символов (так в примере, fibo не определено).

Есть даже вариант импорта всех имен, которые определяет модуль:

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

В данном случае импортируются все имена за исключением тех, которые начинаются с подчеркивания (_). В большинстве случаев программисты на Python не используют такой импорт, поскольку он вводит неизвестное множество имен в интерпретатор, возможно скрытие нескольких объектов, которые вы уже определили.

Заметьте, что в общепринятой практике импортирование * из модуля вызывает неодобрение, поскольку часто это делает код плохо читаемым. Однако это удобно использовать в интерактивной сессии, чтобы меньше набирать.

Примечание: Для повышения эффективности каждый модуль импортируется только однажды за сессию интерпретатора. Следовательно, если вы изменяете ваши модули, вы должны перезапустить интерпретатор, или, если вы просто хотите проверить один модуль в интерактивном режиме, используйте imp.reload(), например, import imp; imp.reload(modulename).

6.1.1. Выполнение модулей как скриптов

Когда вы запускаете модуль Python командой

python fibo.py <arguments>

код в модуле будет выполнен, просто как если бы вы импортировали его, но с __name__ установленным в "__main__". Это означает, что при добавлении этого кода в конец вашего модуля

if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

вы можете сделать файл используемым как скрипт, в то же время он останется импортируемым модулем, потому что код, который разбирает командную строку, запускается только, если модуль выполняется как файл "main" (главный):

$ python fibo.py 50
1 1 2 3 5 8 13 21 34

Если модуль импортируется, то код не выполняется:

>>> import fibo
>>>

Это часто используется либо для обеспечения удобного пользовательского интерфейса к модулю, либо для целей тестирования (при запуске модуля как скрипта выполняется ряд тестов).

6.1.2. Путь поиска модуля

Когда осуществляется импорт модуля по имени spam, сначала интерпретатор ищет встроенные модули с таким именем. Если не находит, то затем ищет файл по имени spam.py в списке каталогов, заданных переменной sys.path. sys.path инициируется из этих мест:

  • Каталог, содержащий выполняемый скрипт (или текущий каталог, когда не указан никакой файл).
  • PYTHONPATH (список имен каталогов, с таким же синтаксисом как переменная оболочки PATH).
  • Умолчания, зависимые от установки.

Примечание: В файловой системе, которая поддерживает символические ссылки, каталог, содержащий запущенный скрипт, обрабатывается после символической ссылки. Другими словами, каталог, содержащий символическую ссылку, не добавляется к пути поиска модуля.

После инициализация программа на Python может изменять sys.path. Директория, содержащая запущенный скрипт, размещается в начале пути поиска, впереди пути стандартной библиотеки. Это означает, что скрипты из данной директории будут загружены вместо модулей с такими же именами в каталоге библиотеки. Если замена не предполагалась, то это ошибка. См. раздел Standard Modules (docs.python.org/3/tutorial/modules.html#tut-standardmodules) для большей информации.

6.1.3. "Скомпилированные" файлы Python

Для ускорения загрузки модулей Python кэширует скомпилированную версию каждого модуля в каталоге __pycache__ под именем module.version.pyc, где версия кодирует формат скомпилированного файла; обычно включает номер версии Python. Например, в CPython релизе 3.3 скомпилированная версия была бы кэширована как __pycache__/spam.cpython-33.pyc. Такое соглашение наименования позволяет компилировать модули из различных релизов и различных версий Python для сосуществования.

Python сравнивает дату изменения исходного кода со скомпилированной версией, чтобы обнаружить, если она устарела и нуждается в перекомпиляции. Это полностью автоматический процесс. Также скомпилированные модули не зависят от платформы, так одна и та же библиотека может быть разделена среди систем с различными архитектурами.

Python не проверяет кэш в двух случаях. Во-первых, он всегда перекомпилирует и не хранит результат для модуля, который загружается прямо из командной строки. Во вторых, он не проверяет кэш, если нет исходного кода модуля. Для поддержки распространения без исходного кода скомпилированный модуль должен быть в каталоге с исходными кодами, и здесь не должно быть исходных кодов модуля.

Некоторые советы для специалистов:

  • Вы можете использовать переключатели -O и -OO в командах Python для уменьшения размера скомпилированного модуля. Переключатель -O удаляет операторы, переключатель -OO удаляет операторы и строки __doc__. Поскольку некоторые программы могут рассчитывать, что все это доступно, вам следует использовать эту опцию, если вы знаете, что делаете. У "оптимизированного" модуля суффикс .pyo вместо .pyc, и он обычно меньше. Будущие релизы могут изменить эффекты оптимизации.
  • Программа не работает быстрее, когда читается из файлов .pyc или .pyo, чем когда она читается из файла .py; единственное, что быстрее для файлов .pyc или .pyo - это скорость с которой они загружаются.
  • Модуль compileall может создавать файлы .pyc (или .pyo при использовании -O) для всех модулей в каталоге.
  • Есть больше информации по этому процессу, включая блок-схему решения, в PEP 3147.