Jak ustawić zmienne środowiskowe w Pythonie

658

Muszę ustawić niektóre zmienne środowiskowe w skrypcie Pythona i chcę, aby wszystkie inne skrypty wywoływane z Pythona widziały ustawione zmienne środowiskowe.

Jeśli zrobię

os.environ["DEBUSSY"] = 1`

narzeka, że 1musi to być sznurek.

Chcę również wiedzieć, jak odczytać zmienne środowiskowe w pythonie (w dalszej części skryptu) po ustawieniu.

prahallada
źródło
powiązane również: youtu.be/ScyxIfOuSXs?t=61
Yannic Hamann
Nie ma związku z pytaniem: czytam ten var. nazwa jako Kot
Ahmed

Odpowiedzi:

790

Zmienne środowiskowe muszą być łańcuchami, więc używaj

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

aby ustawić zmienną DEBUSSYna ciąg 1.

Aby uzyskać dostęp do tej zmiennej później, po prostu użyj:

print(os.environ["DEBUSSY"])

Procesy potomne automatycznie dziedziczą zmienne środowiskowe procesu macierzystego - nie jest wymagane żadne specjalne działanie z Twojej strony.

Sven Marnach
źródło
20
Na niektórych platformach modyfikacja os.environ nie zmodyfikuje środowiska systemowego ani dla bieżącego procesu, ani procesów potomnych. Zobacz dokumentację, aby uzyskać więcej informacji: docs.python.org/2/library/os.html#os.environ
Evan
8
@Evan Mogą istnieć pewne historyczne wersje Uniksa, które nie obsługują putenv(), ale dla tych Uniksów i tak nic nie możesz zrobić. Obsługiwana była nawet stara wersja AIX i HPUX, z którą pracowałem. Jeśli ktoś rzeczywiście jest w stanie znaleźć komputer, który go nie obsługuje, mam poważne wątpliwości, czy uda mu się uruchomić Python na tym komputerze. :)
Sven Marnach
3
Uwaga: cytat z powyższej referencji @ Evan, takie zmiany środowiska wpływają na podprocesy rozpoczęte przez os.system (), popen () lub fork () i execv (). Innymi słowy, należy pamiętać, że to podejście nie zmieni sposobu działania programu, a jedynie sposób działania jego dzieci. To prawda, że ​​twój program może ustawiać i odczytywać zmienne środowiskowe, ale tylko ze środowiska, które konfiguruje dla swoich dzieci. Zobacz także: zmień obecne środowisko procesu . Jak dotąd nie znalazłem sposobu, aby skrypt w języku Python zmodyfikował jego macierzystą env.
CODE-REaD
1
@ SvvenMarnach to stwierdzenie „proces potomny automatycznie dziedziczy środowisko procesu nadrzędnego 'true dla powłoki jak bash.
Krishna Oza
@darth_coder Dotyczy to wszystkich procesów w systemach operacyjnych typu Unix. Nie wiem o innym systemie operacyjnym. Pamiętaj, że zmienne powłoki nie są przechowywane w środowisku, chyba że je wyeksportujesz.
Sven Marnach,
114

Konieczne może być rozważenie dalszych aspektów niezawodności kodu;

gdy przechowujesz zmienną o wartości całkowitej jako zmienną środowiskową, spróbuj

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

następnie w celu pobrania weź pod uwagę, że aby uniknąć błędów, powinieneś spróbować

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

ewentualnie zamień „-1” na „Not Set”

podsumowując to wszystko

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)
znak
źródło
3
Czy możesz powiedzieć, jak ustawić zmienną na komputerze z systemem Linux, czy kod jest taki sam dla wszystkich platform?
Anurag-Sharma
2
Rzadko ma sens przechowywanie -1 dla brakującej liczby całkowitej. Lepszym rozwiązaniem byłoby myvar = int(os.environ.get('MYVAR')) if os.environ.get('MYVAR', '') != '' else None- w ten sposób byłoby Brak, gdyby nie podano numeru
Benjamin Atkin
1
Jeśli masz do czynienia z liczbami całkowitymi, -1 ma sens. Chociaż prawdopodobnie ustawiłbym zmienną / stałą na wartość, której użyłbym dla nie ustawionej (np value_not_set = '-1'.). Następnie możesz użyćdebussy = int(os.environ.get('DEBUSSY', value_not_set))
yeOldeDataSmythe
68

os.environzachowuje się jak słownik Pythona, więc można wykonywać wszystkie typowe operacje słownikowe. Oprócz operacji geti setwymienionych w innych odpowiedziach możemy również po prostu sprawdzić, czy istnieje klucz. Klucze i wartości powinny być przechowywane jako ciągi znaków .

Python 3

W Pythonie 3 słowniki używają słowa kluczowego in zamiast 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'

Należy pamiętać o jednej ważnej rzeczy os.environ:

Chociaż procesy potomne dziedziczą środowisko po procesie nadrzędnym, niedawno natknąłem się na problem i zorientowałem się, że jeśli inne skrypty aktualizują środowisko podczas działania skryptu python, wywołanie os.environponownie nie będzie odzwierciedlało najnowszych wartości .

Fragment dokumentów :

To odwzorowanie jest przechwytywane przy pierwszym imporcie modułu os, zazwyczaj podczas uruchamiania Pythona w ramach przetwarzania site.py. Zmiany w środowisku wprowadzone po tym czasie nie są odzwierciedlane w os.environ, z wyjątkiem zmian dokonanych przez bezpośrednią modyfikację os.environ.

os.environ.data który przechowuje wszystkie zmienne środowiskowe, jest obiektem dict, który zawiera wszystkie wartości środowiskowe:

>>> type(os.environ.data)  # changed to _data since v3.2 (refer comment below)
<type 'dict'>
sisanared
źródło
1
Zmienne środowiskowe procesu są ustawiane podczas tworzenia procesu. Wszelkie późniejsze zmiany nie wpłyną na własną kopię zmiennej środowiskowej procesu. Jest to wspólne dla wszystkich procesów, nie tylko dla Pythona. Ponadto os.environ.dataw Pythonie 3.2 zmieniono jego nazwę na os.environ._dataprefiks podkreślenia pokazujący, że nie należy go czytać bezpośrednio. Zresztą i os.environ._datatak nie zaktualizuje wartości.
Al Sweigart
Tak, teraz rozumiem. Chciałem podzielić się moją wstępną niespodzianką z innymi, którzy szukają. Dziękujemy za wskazanie aktualizacji nazwy zmiennej od wersji 3.2, zaktualizuje odpowiedź.
sisanared
21

jeśli zrobię os.environ ["DEBUSSY"] = 1, narzeka, że ​​1 musi być ciągiem znaków.

Więc zrób

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

Chcę również wiedzieć, jak odczytać zmienne środowiskowe w pythonie (w dalszej części skryptu) po ustawieniu.

Po prostu użyj os.environ["DEBUSSY"], jak w

some_value = os.environ["DEBUSSY"]
Jim Brissom
źródło
19

ustawić zmienną:

Metoda przypisania przedmiotu za pomocą klucza:

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

uzyskać lub sprawdzić, czy istnieje, czy nie,

ponieważ os.environ jest instancją, możesz wypróbować sposób obiektowy.

Metoda 1:

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

otrzyma '1'jako wartość zwracaną

Metoda 2:

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

Metoda 3:

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

Metoda 4:

os.environ.has_key('DEBUSSY') #last 2 methods are Boolean Return so can use for conditional statements
Mohideen bin Mohammed
źródło
16

Powinieneś przypisać wartość ciągu do zmiennej środowiskowej.

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

Jeśli chcesz odczytać lub wydrukować zmienną środowiskową, po prostu użyj

print os.environ["DEBUSSY"]

Zmiany będą obowiązywać tylko w bieżącym procesie, do którego zostały przypisane, nie spowoduje trwałej zmiany wartości. Procesy potomne automatycznie odziedziczą środowisko procesu macierzystego.

wprowadź opis zdjęcia tutaj

RejeeshChandran
źródło
5
„Zmiany będą obowiązywać tylko w bieżącym procesie, do którego zostały przypisane, nie zmieni trwale wartości.” To odpowiedziało na pytanie, jakie miałem na temat zakresu ustawienia zmiennej środowiskowej.
spitfiredd
2
Jeśli wyjdę z powłoki Pythona, a wcześniej ustawiony zestaw środowiska operacyjnego OS zniknie.
MeadowMuffins,
Jak ustawić zmienną środowiskową w systemie Windows? Próbowałem, set [<name>=[<value>]]ale robi to tylko dla bieżącego procesu. Kiedy zamykam cmd, nie istnieje i nawet gdy jest otwarty, inne programy go nie widzą.
Filip
15

Co os.environ["DEBUSSY"] = '1'? Zmienne środowiskowe są zawsze łańcuchami.

ThiefMaster
źródło
14

Próbowałem dodać zmienne środowiskowe. Moim celem było przechowywanie niektórych informacji o użytkownikach w zmiennych systemowych, dzięki czemu mogę używać tych zmiennych w przyszłych rozwiązaniach, jako alternatywę dla plików konfiguracyjnych. Jednak metoda opisana w poniższym kodzie wcale mi nie pomogła.

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

Ten prosty blok kodu działa dobrze, jednak te zmienne istnieją w odpowiednich procesach, tak że nie znajdziesz ich w zakładce zmiennych środowiskowych w ustawieniach systemu Windows. Prawie powyższy kod nie służył mojemu celowi. Ten problem jest omawiany tutaj: problem ze składowaniem zmiennej

os.environ.putenv(key, value)

Kolejna nieudana próba. Wreszcie udało mi się pomyślnie zapisać zmienną w rejestrze środowiska Windows, naśladując polecenia powłoki systemu Windows zawarte w klasie systemowej pakietu OS. Poniższy kod opisuje tę udaną próbę.

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

Mam nadzieję, że będzie to pomocne dla niektórych z was.

Sourabh Desai
źródło
12

Należy zauważyć, że jeśli spróbujesz ustawić zmienną środowiskową na ocenę bash, nie zapiszesz tego, czego oczekujesz. Przykład:

from os import environ

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

Nie będzie to oceniać tak jak w powłoce, więc zamiast uzyskać /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Homeścieżkę, otrzymasz dosłowne wyrażenie $(/usr/libexec/java_home).

Pamiętaj, aby to ocenić przed ustawieniem zmiennej środowiskowej, na przykład:

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}")
Josh Correia
źródło
11

Możesz użyć os.environsłownika, aby uzyskać dostęp do zmiennych środowiskowych.

Problem, który miałem, polega na tym, że gdybym spróbował os.systemuruchomić plik wsadowy, który ustawia zmienne środowiskowe (używając polecenia SET w pliku **. Bat *), tak naprawdę nie ustawiłby ich dla twojego środowiska python (ale dla proces potomny utworzony za pomocą os.systemfunkcji). Aby faktycznie uzyskać zmienne ustawione w środowisku python, używam tego skryptu:

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
Ricardo Alejos
źródło
9

Podczas gry ze zmiennymi środowiskowymi (dodawaj / modyfikuj / usuwaj zmienne) dobrą praktyką jest przywrócenie poprzedniego stanu po zakończeniu funkcji.

Możesz potrzebować czegoś takiego, jak modified_environmenedżer kontekstu opisany w tym pytaniu, aby przywrócić zmienne środowiskowe.

Klasyczne zastosowanie:

with modified_environ(DEBUSSY="1"):
    call_my_function()
Laurent LAPORTE
źródło