Шаг 191.
Python: сборник рецептов.
Модули и пакеты. Добавление каталогов в sys.path

    На этом шаге мы рассмотрим способ решения указанной задачи.

Задача

    У вас есть код Python, который не импортируется, потому что он не размещен в одном из каталогов, перечисленных в sys.path. Вы хотели бы добавить новые каталоги в путь поиска Python, но не хотите "зашивать" их в свой код.

Решение

    Есть два распространенных приема, которые позволяют добавить новые каталоги в sys.path. Во-первых, вы можете добавить их через переменную окружения PYTHONPATH. Например:

bash % env PYTHONPATH=/some/dir:/other/dir python3
Python 3.3.0 (default, Oct 4 2012, 10:17:33)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/some/dir', '/other/dir', ...]
>>>

    В вашем собственном приложении эту переменную можно менять при запуске программы или через скрипт программной оболочки.

    Второй подход - создать файл .pth, в котором перечисляются каталоги:

# myapplication.pth
/some/dir
/other/dir

    Этот файл .pth нужно поместить в один из каталогов site-packages Python, которые обычно расположены примерно тут: /usr/local/lib/python3.3/site-packages или ~/.local/lib/python3.3/site-packages. При запуске интерпретатора перечисленные в этом файле каталоги будут добавлены в sys.path, если они присутствуют в файловой системе. Добавление файлов .pth может потребовать доступа на уровне администратора системы, если файлы добавляются к системному интерпретатору Python.

Обсуждение

    Столкнувшись с проблемой определения местоположения файлов, вы можете склоняться к написанию кода, который вручную правит значение sys.path. Например:

import sys

sys.path.insert(0, '/some/dir') 
sys.path.insert(0, '/other/dir')

    Хотя это "работает", но на практике порождает крайне хрупкий код. Этого нужно избегать. Недостаток данного подхода в том, что он жестко прописывает имена каталогов в исходном коде. Это может вызывать проблемы с поддержкой, если ваш код будет перемещен. Обычно гораздо лучше конфигурировать пути способом, который можно настраивать, не копаясь в исходниках.

    Иногда вы можете обойти проблему жесткого прописывания каталогов, если аккуратно сконструируете подходящий абсолютный путь, используя переменные уровня модуля, такие как __file__. Например:

import sys
from os.path import abspath, join, dirname 

sys.path.insert(0, abspath(dirname('__file__'), 'src'))

    Это добавляет каталог src в путь поиска таким образом, что этот каталог оказывается размещен в том же каталоге, что и код, который выполняет шаг вставки.

    В каталоги site-packages обычно инсталлируются сторонние модули и пакеты. Если ваш код был установлен таким образом, то он будет находиться там. Хотя файлы .pth для конфигурирования пути поиска должны быть размещены в site-packages, они могут ссылаться на любые каталоги в системе. Таким образом вы можете поместить ваш код в совершенно другой набор каталогов, если эти каталоги включены в файл .pth.

    На следующем шаге мы рассмотрим импортирование модулей с использованием имени, передаваемого в форме строки.




Предыдущий шаг Содержание Следующий шаг