Рубрики
Без рубрики

сайт – Конфигурация всего сайта

Автор оригинала: 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

Смотрите также