Выбрать главу

>>> import os

>>> os.environ.keys()

KeysView(<os._Environ object at 0x013B8C70>)

>>> list(os.environ.keys())

[‘TMP’, ‘COMPUTERNAME’, ‘USERDOMAIN’, ‘PSMODULEPATH’, ‘ COMMONPROGRAMFILES’, ...множество строк было удалено...

‘NUMBER_OF_PROCESSORS’, ‘PROCESSOR_LEVEL’, ‘USERPROFILE’, ‘OS’, ‘PUBLIC’, ‘QTJAVA’]

>>> os.environ['TEMP']

‘C:\\Users\\mark\\AppData\\Local\\Temp’

Здесь метод keys возвращает итерируемый объект со списком установленных переменных, а операция индексирования возвращает значение переменной TEMP в Windows. В Linux эти инструкции действуют точно так же, но обычно при запуске Python устанавливаются другие переменные. Поскольку нам знакома переменная PYTHONPATH, посмотрим в Python на ее значение и убедимся в его правильности (когда я писал эти строки, в эту переменную временно был добавлен путь к корневому каталогу с примерами к четвертому изданию книги):

>>> os.environ['PYTHONPATH']

‘C:\\PP4thEd\\Examples;C:\\Users\\Mark\\temp’

>>> for srcdir in os.environ['PYTHONPATH'].split(os.pathsep):

... print(srcdir)

C:\PP4thEd\Examples

C:\Users\Mark\temp

>>> import sys >>> sys.path[:3]

[‘’, ‘C:\\PP4thEd\\Examples’, ‘C:\\Users\\Mark\\temp’]

Переменная PYTHONPATH содержит строку, содержащую список каталогов, разделенных символом, используемым для разделения таких элементов пути на вашей платформе (например, ; в DOS/Windows, : в Unix и Linux). Чтобы разделить эту строку на составляющие, передадим строковому методу split разделитель os.pathsep (переносимая константа, дающая правильный разделитель для соответствующей системы). Как обычно, фактический путь поиска, используемый во время выполнения, хранится в списке sys.path и является объединением пути к текущему рабочему каталогу и содержимого переменной окружения PYTHONPATH.

Изменение переменных оболочки

Как и обычные словари, объект os.environ поддерживает обращение по ключу и присваивание. Операция присваивания, применяемая к словарям, изменяет значение ключа:

>>> os.environ['TEMP']

‘C:\\Users\\mark\\AppData\\Local\\Temp >>> os.environ['TEMP'] = r'c:\temp'

>>> os.environ['TEMP']

‘c:\\temp’

Но в данном случае выполняются некоторые дополнительные действия. Во всех последних версиях Python значения, присваиваемые ключам os.environ таким способом, автоматически экспортируются в другие части приложения. То есть присваивание по ключу изменяет не только объект os.environ в программе, но и соответствующую переменную в окружении оболочки для процесса выполняемой программы. Новое значение переменной становится видимым программе на языке Python, всем связанным с ней модулям на языке C и всем программам, порождаемым процессом Python.

За кулисами при присваивании объекту os.environ по ключу происходит вызов os.putenv - функции, изменяющей переменную окружения за границами интерпретатора Python. Чтобы показать, как это работает, нам потребуется пара сценариев, которые изменяют и получают значения переменных оболочки. Первый из них приводится в примере 3.3.

Пример 3.3. PP4E\System\Environment\setenv.py

import os

print(‘setenv...’, end=’ ‘)

print(os.environ[‘USER’]) # выведет текущее значение переменной оболочки

os.environ[‘USER’] = ‘Brian’ # неявно вызовет функцию os.putenv os.system(‘python echoenv.py’)

os.environ[‘USER’] = ‘Arthur’ # изменение передается порождаемым программам os.system(‘python echoenv.py’) # и связанным с процессом библ. модулям на C

os.environ[‘USER’] = input(‘?’) print(os.popen(‘python echoenv.py’).read())

Данный сценарий setenv.py просто изменяет переменную оболочки USER и запускает другой сценарий, выводящий значение этой переменной, который приводится в примере 2.5.

Пример 3.4. PP4E\System\Environment\echoenv.py

import os

print(‘echoenv...’, end=’ ‘) print(‘Hello,’, os.environ[‘USER’])

Независимо от способа запуска сценарий echoenv.py выводит значение переменной окружения USER. При запуске из командной строки этот сценарий выведет значение, установленное нами в самой оболочке:

C:\...\PP4E\System\Environment> set USER=Bob

C:\...\PP4E\System\Environment> python echoenv.py echoenv... Hello, Bob

Однако при запуске из другого сценария, например, из setenv.py, с помощью функции os.system или os.popen, с которыми мы познакомились ранее, сценарий echoenv.py получит то значение переменной USER, которое было установлено родительской программой:

C:\...\PP4E\System\Environment> python setenv.py

setenv... Bob

echoenv... Hello, Brian

echoenv... Hello, Arthur

?Gumby

echoenv... Hello, Gumby

C:\...\PP4E\System\Environment> echo %USER%

Bob

Точно так же этот механизм действует и в Linux. Вообще говоря, порождаемая программа всегда наследует значения переменных окружения от своих родителей. Порожденными программами являются такие, которые запускаются средствами Python, например os.spawnv, комбинацией os.fork/exec в Unix-подобных системах, и os.popen, os.system или с помощью модуля subprocess на ряде других платформ. Все программы, запущенные таким способом, получают значения переменных окружения, существующие в момент запуска в родительском процессе.9