Автор оригинала: Doug Hellmann.
Модуль site
обрабатывает конфигурацию сайта, особенно путь импорта.
Путь импорта
site
автоматически импортируется каждый раз при запуске интерпретатора. При импорте он расширяет sys.path
специфичными для сайта именами, созданными путем объединения значений префикса sys.prefix
и sys.exec_prefix
с несколькими суффиксами. Используемые значения префиксов сохраняются в переменной уровня модуля PREFIXES
для дальнейшего использования. В Windows суффиксами являются пустая строка и lib/site-packages
. Для Unix-подобных платформ значениями являются lib/python $ version/site-packages
(где $ version
заменяется на основной и дополнительный номер версии интерпретатора, например как 3.5
) и lib/site-python
.
site_import_path.py
import sys import os import site if 'Windows' in sys.platform: SUFFIXES [ '', 'lib/site-packages', ] else: SUFFIXES [ 'lib/python{}/site-packages'.format(sys.version[:3]), 'lib/site-python', ] print('Path prefixes:') for p in site.PREFIXES: print(' ', p) for prefix in sorted(set(site.PREFIXES)): print() print(prefix) for suffix in SUFFIXES: print() print(' ', suffix) path os.path.join(prefix, suffix).rstrip(os.sep) print(' exists :', os.path.exists(path)) print(' in path:', path in sys.path)
Каждый из путей, полученных в результате комбинаций, проверяется, а существующие добавляются в sys.path
. В этих выходных данных показана версия платформы Python, установленная в системе Mac OS X.
$ python3 site_import_path.py Path prefixes: /Library/Frameworks/Python.framework/Versions/3.5 /Library/Frameworks/Python.framework/Versions/3.5 /Library/Frameworks/Python.framework/Versions/3.5 lib/python3.5/site-packages exists : True in path: True lib/site-python exists : False in path: False
Каталоги пользователей
В дополнение к глобальным путям пакетов сайтов, site
отвечает за добавление пользовательских местоположений в путь импорта. Все пользовательские пути основаны на каталоге USER_BASE
, который обычно расположен в части файловой системы, принадлежащей текущему пользователю (и доступной для записи). Внутри каталога USER_BASE
находится каталог site-packages
, путь к которому доступен как USER_SITE
.
site_user_base.py
import site print('Base:', site.USER_BASE) print('Site:', site.USER_SITE)
Имя пути USER_SITE
создается с использованием тех же значений суффикса для конкретной платформы, которые описаны ранее.
$ python3 site_user_base.py Base: /Users/dhellmann/.local Site: /Users/dhellmann/.local/lib/python3.7/site-packages
Базовый каталог пользователя может быть установлен с помощью переменной среды PYTHONUSERBASE
и имеет значения по умолчанию для конкретной платформы ( ~/Python $ version/site-packages
для Windows и ~/.local
для не Windows).
$ Base: /tmp/dhellmann Site: /tmp/dhellmann/lib/python3.7/site-packages
Каталог пользователя отключен при некоторых обстоятельствах, которые могут вызвать проблемы с безопасностью (например, если процесс выполняется с другим эффективным пользователем или идентификатором группы, чем фактический пользователь, который его запустил). Приложение может проверить настройку, проверив ENABLE_USER_SITE
.
site_enable_user_site.py
import site status { None: 'Disabled for security', True: 'Enabled', False: 'Disabled by command-line option', } print('Flag :', site.ENABLE_USER_SITE) print('Meaning:', status[site.ENABLE_USER_SITE])
Каталог пользователя также можно явно отключить в командной строке с помощью -s
.
$ python3 site_enable_user_site.py Flag : True Meaning: Enabled $ python3 -s site_enable_user_site.py Flag : False Meaning: Disabled by command-line option
Файлы конфигурации пути
По мере добавления путей к пути импорта они также сканируются на наличие файлов конфигурации пути . Файл конфигурации пути – это простой текстовый файл с расширением .pth
. Каждая строка в файле может принимать одну из четырех форм.
- Полный или относительный путь к другому местоположению, который следует добавить к пути импорта.
- Выполняемый оператор Python. Все такие строки должны начинаться с оператора
import
. - Пустые строки игнорируются.
- Строка, начинающаяся с
#
, рассматривается как комментарий и игнорируется.
Файлы конфигурации пути можно использовать для расширения пути импорта для поиска в местах, которые не были бы добавлены автоматически. Например, пакет setuptools
добавляет путь к easy-install.pth
, когда он устанавливает пакет в режиме разработки с помощью python setup.py develop
.
Функция расширения sys.path
является общедоступной, и ее можно использовать в примерах программ, чтобы показать, как работают файлы конфигурации пути. Для каталога с именем with_modules
, содержащего файл mymodule.py
с этим оператором print
, показывающим, как был импортирован модуль:
with_modules/mymodule.py
import os print('Loaded {} from {}'.format( __name__, __file__[len(os.getcwd()) + 1:]) )
Этот скрипт показывает, как additedir ()
расширяет путь импорта, чтобы интерпретатор мог найти нужный модуль.
site_addsitedir.py
import site import os import sys script_directory os.path.dirname(__file__) module_directory os.path.join(script_directory, sys.argv[1]) try: import mymodule except ImportError as err: print('Could not import mymodule:', err) print() before_len len(sys.path) site.addsitedir(module_directory) print('New paths:') for p in sys.path[before_len:]: print(p.replace(os.getcwd(), '.')) # shorten dirname print() import mymodule
После добавления каталога, содержащего модуль, в sys.path
сценарий может без проблем импортировать mymodule
.
$ python3 site_addsitedir.py with_modules Could not import mymodule: No module named 'mymodule' New paths: ./with_modules Loaded mymodule from with_modules/mymodule.py
Изменение пути с помощью additedir ()
выходит за рамки простого добавления аргумента в sys.path
. Если каталог, указанный для additedir ()
, включает любые файлы, соответствующие шаблону * .pth
, они загружаются как файлы конфигурации пути. Учитывая структуру каталогов, подобную следующей
with_pth ├── pymotw.pth └── subdir └── mymodule.py
Если with_pth/pymotw.pth
содержит
# Add a single subdirectory to the path. ./subdir
тогда with_pth/subdir/mymodule.py
можно импортировать, добавив with_pth
в качестве каталога сайта, даже если модуль не находится в этом каталоге, потому что оба with_pth
и with_pth/subdir
добавляются к пути импорта.
$ python3 site_addsitedir.py with_pth Could not import mymodule: No module named 'mymodule' New paths: ./with_pth ./with_pth/subdir Loaded mymodule from with_pth/subdir/mymodule.py
Если каталог сайта содержит несколько файлов .pth
, они обрабатываются в алфавитном порядке.
$ ls -F multiple_pth a.pth b.pth from_a/ from_b/ $ cat multiple_pth/a.pth ./from_a $ cat multiple_pth/b.pth ./from_b
В этом случае модуль находится в multiple_pth/from_a
, поскольку a.pth
читается до b.pth
.
$ python3 site_addsitedir.py multiple_pth Could not import mymodule: No module named 'mymodule' New paths: ./multiple_pth ./multiple_pth/from_a ./multiple_pth/from_b Loaded mymodule from multiple_pth/from_a/mymodule.py
Настройка конфигурации сайта
Модуль site
также отвечает за загрузку настроек для всего сайта, определенных владельцем локального сайта в модуле sitecustomize
. Использование sitecustomize
включает расширение пути импорта и включение покрытия, профилирования или других инструментов разработки.
Например, этот сценарий sitecustomize.py
расширяет путь импорта с помощью каталога на основе текущей платформы. Путь, зависящий от платформы, в /opt/python
добавляется к пути импорта, поэтому любые установленные там пакеты можно импортировать. Подобная система полезна для совместного использования пакетов, содержащих скомпилированные модули расширения, между хостами в сети через общую файловую систему. На каждом хосте необходимо установить только сценарий sitecustomize.py
, а доступ к другим пакетам можно получить с файлового сервера.
with_sitecustomize/sitecustomize.py
print('Loading sitecustomize.py') import site import platform import os import sys path os.path.join('/opt', 'python', sys.version[:3], platform.platform(), ) print('Adding new path', path) site.addsitedir(path)
Можно использовать простой сценарий, чтобы показать, что sitecustomize.py
импортирован до того, как Python начнет запускать ваш собственный код.
with_sitecustomize/site_sitecustomize.py
import sys print('Running main program from\n{}'.format(sys.argv[0])) print('End of path:', sys.path[-1])
Поскольку sitecustomize
предназначен для общесистемной конфигурации, его следует установить где-нибудь по пути по умолчанию (обычно в каталоге site-packages
). В этом примере PYTHONPATH
явно задается, чтобы обеспечить захват модуля.
$ e_sitecustomize.py Loading sitecustomize.py Adding new path /opt/python/3.7/Darwin-18.0.0-x86_64-i386-64bit Running main program from with_sitecustomize/site_sitecustomize.py End of path: /opt/python/3.7/Darwin-18.0.0-x86_64-i386-64bit
Настройка конфигурации пользователя
Подобно sitecustomize
, модуль usercustomize
можно использовать для установки пользовательских настроек при каждом запуске интерпретатора. usercustomize
загружается после sitecustomize
, поэтому настройки для всего сайта можно переопределить.
В средах, где домашний каталог пользователя совместно используется на нескольких серверах, работающих под управлением разных операционных систем или версий, стандартный механизм каталогов пользователя может не работать для пользовательских установок пакетов. В этих случаях вместо этого можно использовать дерево каталогов для конкретной платформы.
with_usercustomize/usercustomize.py
print('Loading usercustomize.py') import site import platform import os import sys path os.path.expanduser(os.path.join('~', 'python', sys.version[:3], platform.platform(), )) print('Adding new path', path) site.addsitedir(path)
Другой простой сценарий, похожий на тот, который используется для sitecustomize
, можно использовать, чтобы показать, что usercustomize.py
импортируется до того, как Python запустит другой код.
with_usercustomize/site_usercustomize.py
import sys print('Running main program from\n{}'.format(sys.argv[0])) print('End of path:', sys.path[-1])
Поскольку usercustomize
предназначен для пользовательской конфигурации для пользователя, его следует установить где-нибудь по пути пользователя по умолчанию, но не по пути всего сайта. Каталог USER_BASE
по умолчанию – хорошее место. В этом примере PYTHONPATH
явно задается, чтобы обеспечить захват модуля.
$ _usercustomize.py Loading usercustomize.py Adding new path /Users/dhellmann/python/3.5/Darwin-15.5.0-x86_64\ -i386-64bit Running main program from with_usercustomize/site_usercustomize.py End of path: /Users/dhellmann/python/3.5/Darwin-15.5.0-x86_64\ -i386-64bit
Когда функция каталога сайта пользователя отключена, usercustomize
не импортируется, независимо от того, находится ли он в каталоге сайта пользователя или где-то еще.
$ ite_usercustomize.py Running main program from with_usercustomize/site_usercustomize.py End of path: /Users/dhellmann/Envs/pymotw35/lib/python3.5/site- packages
Отключение модуля сайта
Чтобы поддерживать обратную совместимость с версиями Python до добавления автоматического импорта, интерпретатор принимает параметр -S
.
$ python3 -S site_import_path.py Path prefixes: /Users/dhellmann/Envs/pymotw37/bin/.. /Users/dhellmann/Envs/pymotw37/bin/.. /Users/dhellmann/Envs/pymotw37/bin/.. lib/python3.7/site-packages exists : True in path: False lib/site-python exists : False in path: False
Смотрите также
- стандартная библиотека документации для сайта
- Модули и импорт – описание того, как работает путь импорта, определенный в
sys
. - setuptools – библиотека упаковки и инструмент установки
easy_install
. - Запуск кода при запуске Python – сообщение Неда Батчелдера, в котором обсуждаются способы заставить интерпретатор Python запускать собственный код инициализации перед запуском выполнение основной программы.