Как установить переменные среды в Python

658

Мне нужно установить некоторые переменные окружения в скрипте python, и я хочу, чтобы все остальные скрипты, которые вызываются из python, видели набор переменных окружения.

Если я сделаю

os.environ["DEBUSSY"] = 1`

он жалуется, говоря, что 1должен быть строкой.

Я также хочу знать, как читать переменные окружения в python (в более поздней части скрипта), как только я его установлю.

prahallada
источник
также связано: youtu.be/ScyxIfOuSXs?t=61
Янник Хаманн
Не имеет отношения к вопросу: я читал эту вар. имя как Кот
Ахмед

Ответы:

790

Переменные среды должны быть строками, поэтому используйте

os.environ["DEBUSSY"] = "1"

установить переменную DEBUSSYв строку 1.

Чтобы получить доступ к этой переменной позже, просто используйте:

print(os.environ["DEBUSSY"])

Дочерние процессы автоматически наследуют переменные среды родительского процесса - никаких специальных действий с вашей стороны не требуется.

Свен Марнах
источник
20
На некоторых платформах изменение os.environ не приведет к изменению системной среды ни для текущего процесса, ни для дочерних процессов. См. Документы для получения дополнительной информации: docs.python.org/2/library/os.html#os.environ
Evan
8
@Evan Могут быть некоторые исторические варианты Unix, которые не поддерживают putenv(), но для этих Unixen вы ничего не можете сделать в любом случае. Даже старая версия AIX и HPUX, с которыми я работал, поддерживала ее. Если кто-то действительно сможет найти компьютер, не поддерживающий его сегодня, у меня есть серьезные сомнения, что он сможет запустить Python на этом компьютере. :)
Свен Марнач
3
Осторожно: цитируя приведенную выше ссылку @Evan , такие изменения среды влияют на подпроцессы, запущенные с os.system (), popen () или fork () и execv (). Другими словами, имейте в виду, что этот подход не изменит способ работы вашей программы, а только то, как работают ее дети. Правда, ваша программа может устанавливать и считывать переменные среды, но только из среды, которую она настраивает для своих дочерних элементов. Смотрите также: изменить текущую среду процесса . До сих пор я не нашел способ для сценария Python изменить его родительский env.
КОД-ЧИТАТЬ
1
@SvenMarnach - это утверждение «дочерний процесс автоматически наследует среду родительского процесса», верно для оболочки типа bash.
Кришна Оза,
@darth_coder Это верно для всех процессов в Unix-подобных операционных системах. Я не знаю о другой операционной системе. Обратите внимание, что переменные оболочки не хранятся в среде, пока вы не экспортируете их.
Свен Марнах
114

Возможно, вам придется рассмотреть некоторые дополнительные аспекты надежности кода;

когда вы сохраняете целочисленную переменную как переменную окружения, попробуйте

os.environ['DEBUSSY'] = str(myintvariable)

затем для извлечения учтите, что во избежание ошибок следует попробовать

os.environ.get('DEBUSSY', 'Not Set')

возможно, заменить «-1» на «Не установлено»

так что, чтобы положить все это вместе

myintvariable = 1
os.environ['DEBUSSY'] = str(myintvariable)
strauss = int(os.environ.get('STRAUSS', '-1'))
# NB KeyError <=> strauss = os.environ['STRAUSS']
debussy = int(os.environ.get('DEBUSSY', '-1'))

print "%s %u, %s %u" % ('Strauss', strauss, 'Debussy', debussy)
отметка
источник
3
Можете ли вы сказать, как установить переменную на компьютере с Linux, является ли код одинаковым для всех платформ?
Анураг-Шарма
2
Редко имеет смысл хранить -1 для отсутствующего целого числа. Лучшая ставка была бы myvar = int(os.environ.get('MYVAR')) if os.environ.get('MYVAR', '') != '' else None- таким образом, это было бы Нет, если бы не было предоставлено число
Бенджамин Аткин
1
Если вы имеете дело с целыми числами, то -1 имеет смысл. Хотя я бы, вероятно, установил переменную / константу в значение, которое я бы использовал для не заданного значения (например, value_not_set = '-1'). Тогда вы можете использоватьdebussy = int(os.environ.get('DEBUSSY', value_not_set))
yeOldeDataSmythe
68

os.environведет себя как словарь Python, так что все общие словарные операции могут быть выполнены. В дополнении к getи setоперациям , упомянутых в других ответах, мы можем просто проверить , если ключ существует. Ключи и значения должны храниться в виде строк .

Python 3

Для python 3 словари используют ключевое слово in вместо has_key

>>> import os
>>> 'HOME' in os.environ  # Check an existing env. variable
True
...

Python 2

>>> import os
>>> os.environ.has_key('HOME')  # Check an existing env. variable
True
>>> os.environ.has_key('FOO')   # Check for a non existing variable
False
>>> os.environ['FOO'] = '1'     # Set a new env. variable (String value)
>>> os.environ.has_key('FOO')
True
>>> os.environ.get('FOO')       # Retrieve the value
'1'

Есть одна важная вещь, которую стоит отметить при использовании os.environ :

Хотя дочерние процессы наследуют среду от родительского процесса, я недавно столкнулся с проблемой и выяснил, что если у вас есть другие сценарии, обновляющие среду во время работы сценария python, os.environповторный вызов не будет отражать последние значения .

Выдержка из документов :

Это сопоставление фиксируется при первом импорте модуля os, обычно во время запуска Python, как часть обработки site.py. Изменения в среде, сделанные после этого времени, не отражаются в os.environ, за исключением изменений, внесенных путем непосредственного изменения os.environ.

os.environ.data который хранит все переменные окружения, является объектом dict, который содержит все значения окружения:

>>> type(os.environ.data)  # changed to _data since v3.2 (refer comment below)
<type 'dict'>
sisanared
источник
1
Переменные среды процесса устанавливаются при его создании. Любые изменения, внесенные после этого, не влияют на собственную копию процесса переменной среды. Это общее для всех процессов, а не только для Python. Дальше,os.environ.data в Python 3.2 он был переименован в os.environ._dataпрефикс подчеркивания, показывающий, что вы не должны читать его напрямую. Во всяком случае, os.environ._dataне будет обновленных значений в любом случае.
Аль Суигарт,
Да, теперь я понимаю. Я хотел поделиться своим первоначальным сюрпризом с другими, которые приходят посмотреть. Спасибо за указание на обновление имени переменной начиная с 3.2, обновит ответ.
Сисанаред
21

если я делаю os.environ ["DEBUSSY"] = 1, он жалуется, говоря, что 1 должен быть строкой.

Тогда делай

os.environ["DEBUSSY"] = "1"

Я также хочу знать, как читать переменные окружения в python (в более поздней части скрипта), как только я его установлю.

Просто используйте os.environ["DEBUSSY"], как в

some_value = os.environ["DEBUSSY"]
Джим Бриссом
источник
19

установить переменную:

Метод назначения элемента по ключу:

import os    
os.environ['DEBUSSY'] = '1'  #Environ Variable must be string not Int

получить или проверить, существует ли он или нет,

с тех пор - это экземпляр, вы можете попробовать объектный путь.

Способ 1:

os.environ.get('DEBUSSY') # this is error free method if not will return None by default

получите '1' качестве возвращаемого значения

Способ 2:

os.environ['DEBUSSY'] # will throw an key error if not found!

Способ 3:

'DEBUSSY' in os.environ  # will return Boolean True/False

Способ 4:

os.environ.has_key('DEBUSSY') #last 2 methods are Boolean Return so can use for conditional statements
Мохидин бен Мухаммед
источник
16

Вы должны присвоить строковое значение переменной среды.

os.environ["DEBUSSY"] = "1"

Если вы хотите прочитать или распечатать переменную окружения, просто используйте

print os.environ["DEBUSSY"]

Эти изменения вступят в силу только для текущего процесса, которому он был назначен, и не изменит значение навсегда. Дочерние процессы автоматически наследуют среду родительского процесса.

введите описание изображения здесь

RejeeshChandran
источник
5
«Эти изменения вступят в силу только для текущего процесса, в котором они были назначены, и они не изменят значение навсегда». На этот вопрос я ответил на вопрос о том, как установить переменную окружения.
spitfiredd
2
Если я выйду из оболочки python, а ранее установленный набор os-среды пропал.
MeadowMuffins
Как мне установить переменную среды в Windows? Я пытался, set [<name>=[<value>]]но это только для текущего процесса. Когда я закрываю cmd, он не существует, и даже когда он открыт, другие программы не видят его.
Филип
15

Как насчет os.environ["DEBUSSY"] = '1'? Переменные среды всегда являются строками.

ThiefMaster
источник
14

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

import os
os.environ["variable_1"] = "value_1"
os.environ["variable_2"] = "value_2"
# To Verify above code
os.environ.get("variable_1")
os.environ.get("variable_2")

Этот простой блок кода работает хорошо, однако эти переменные существуют внутри соответствующих процессов, так что вы не найдете их на вкладке переменных среды системных настроек Windows. Приведенный выше код не служил моей цели. Эта проблема обсуждается здесь: проблема сохранения переменной

os.environ.putenv(key, value)

Еще одна неудачная попытка. Итак, наконец, мне удалось успешно сохранить переменную в регистре среды окна, имитируя команды оболочки Windows, заключенные в системный класс пакета os. Следующий код описывает эту успешную попытку.

os.system("SETX {0} {1} /M".format(key, value))

Я надеюсь, что это будет полезно для некоторых из вас.

Сураб Десаи
источник
12

Следует отметить, что если вы попытаетесь установить переменную окружения для оценки bash, она не будет хранить то, что вы ожидаете. Пример:

from os import environ

environ["JAVA_HOME"] = "$(/usr/libexec/java_home)"

Это не будет оцениваться как в оболочке, поэтому вместо /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Homeпути вы получите буквальное выражение $(/usr/libexec/java_home).

Обязательно оцените его перед установкой переменной среды, например так:

from os import environ
from subprocess import Popen, PIPE

bash_variable = "$(/usr/libexec/java_home)"
capture = Popen(f"echo {bash_variable}", stdout=PIPE, shell=True)
std_out, std_err = capture.communicate()
return_code = capture.returncode

if return_code == 0:
    evaluated_env = std_out.decode().strip()
    environ["JAVA_HOME"] = evaluated_env
else:
    print(f"Error: Unable to find environment variable {bash_variable}")
Джош Коррейя
источник
11

Вы можете использовать os.environсловарь для доступа к переменным среды.

Теперь проблема, с которой я столкнулся, заключается в том, что если бы я попытался использовать os.systemдля запуска командного файла, который устанавливает переменные среды (используя команду SET в файле **. Bat *), он не установил бы их для вашей среды Python (но для дочерний процесс, который создается с помощью os.systemфункции). Чтобы получить переменные, установленные в среде Python, я использую этот скрипт:

import re
import system
import os

def setEnvBat(batFilePath, verbose = False):
    SetEnvPattern = re.compile("set (\w+)(?:=)(.*)$", re.MULTILINE)
    SetEnvFile = open(batFilePath, "r")
    SetEnvText = SetEnvFile.read()
    SetEnvMatchList = re.findall(SetEnvPattern, SetEnvText)

    for SetEnvMatch in SetEnvMatchList:
        VarName=SetEnvMatch[0]
        VarValue=SetEnvMatch[1]
        if verbose:
            print "%s=%s"%(VarName,VarValue)
        os.environ[VarName]=VarValue
Рикардо Алехос
источник
9

Когда вы играете с переменными среды (добавляете / модифицируете / удаляете переменные), хорошей практикой является восстановление предыдущего состояния при завершении функции.

Вам может понадобиться что-то вроде modified_environконтекстного менеджера, описанного в этом вопросе для восстановления переменных среды.

Классическое использование:

with modified_environ(DEBUSSY="1"):
    call_my_function()
Лоран Лапорт
источник