>>> 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