Як встановити змінні середовища в Python


658

Мені потрібно встановити деякі змінні середовища в скрипті python, і я хочу, щоб усі інші сценарії, які викликаються з python, бачили набір змінних середовища.

Якщо я це роблю

os.environ["DEBUSSY"] = 1`

він скаржиться, кажучи, що 1це повинно бути рядком.

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



також пов’язано: youtu.be/ScyxIfOuSXs?t=61
Yannic Hamann

Не пов'язане з питанням: я прочитав цю вар. ім'я як Кіт
ахмед

Відповіді:


790

Змінні середовища повинні бути рядками, тому використовуйте

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

щоб встановити змінну DEBUSSYна рядок 1.

Щоб пізніше отримати доступ до цієї змінної, просто скористайтеся:

print(os.environ["DEBUSSY"])

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


20
На деяких платформах модифікація os.environ фактично не змінює системне середовище ні для поточного процесу, ні для дочірніх процесів. Докладнішу інформацію див. У документах: docs.python.org/2/library/os.html#os.environ
Еван

8
@Evan Можливо, є деякі історичні варіанти Unix, які не підтримують putenv(), але для цих Unixen все одно ви нічого не можете зробити. Навіть стара версія AIX та HPUX, з якою я працював, підтримувала її. Якщо хтось насправді зможе знайти комп’ютер, який не підтримує його сьогодні, у мене є серйозні сумніви, що вони зможуть запустити Python на цьому комп’ютері. :)
Свен Марнах

3
Застереження: цитувати з посилання на Евана вище: Такі зміни в середовищі впливають на підпроцеси, розпочаті з os.system (), popen () або fork () та execv (). Іншими словами, пам’ятайте, що такий підхід не змінює спосіб роботи вашої програми, а лише те, як працюють діти вашої програми. Правда, ваша програма може встановлювати та читати змінні середовища, але лише з оточення, яке вона налаштовує для своїх дітей. Див. Також: зміна поточного середовища процесу . Поки що я не знайшов способу сценарію Python змінити свою батьківську оточення.
CODE-READ

1
@SvenMarnach - це твердження "дочірній процес автоматично успадковує середовище батьківського процесу" істинно для оболонки, як баш.
Кришна Оза,

@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операціями , згаданих в інших відповідях, ми можемо просто перевірити , якщо ключ існує. Ключі та значення повинні зберігатися у вигляді рядків .

Пітон 3

Для Python 3, словники використовують в ключовому слові замість has_key

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

Пітон 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'>

1
Змінні середовища середовища встановлюються при створенні процесу. Будь-які зміни, внесені після цього, не впливатимуть на власну копію змінної середовища. Це властиво всім процесам, не тільки Python. Крім того, os.environ.dataбуло перейменовано в Python 3.2 to os.environ._data, префікс підкреслення, який показує, що ви не повинні читати його безпосередньо. Так чи інакше, os.environ._dataоновлені значення все одно не матимуть.
Al Sweigart

Так, зараз я розумію. Я хотів поділитися своїм початковим сюрпризом з іншими, хто приходить шукати. Дякуємо, що вказали на оновлення назви змінної з 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

отримати чи перевірити, чи існував він чи ні,

оскільки os.environ - це екземпляр, ви можете спробувати об'єктний спосіб.

Спосіб 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"]

Ці зміни будуть ефективними лише для поточного процесу, де він був призначений, він не змінить значення назавжди. Дочірні процеси автоматично успадковують середовище батьківського процесу.

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


5
"Ці зміни будуть ефективними лише для поточного процесу, де він був призначений. Це значення не змінитиме остаточно". Це відповів на запитання, яке я мав про сферу встановлення змінної середовища.
spitfiredd

2
Якщо я вийду з оболонки python, і раніше встановлений OS-середовище не буде.
MeadowMuffins

Як встановити змінну середовища у Windows? Я спробував, set [<name>=[<value>]]але це робить це лише для поточного запущеного процесу. Коли я закриваю cmd, його не існує, навіть коли він відкритий, інші програми не можуть його бачити.
Філіп

15

Про що os.environ["DEBUSSY"] = '1'? Змінні середовища завжди є рядками.


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

Слід зазначити, що якщо ви спробуєте встановити змінну середовища для баш-оцінки, вона не збереже те, що ви очікуєте. Приклад:

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()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.