Come impostare le variabili di ambiente in Python


658

Devo impostare alcune variabili di ambiente nello script di Python e voglio che tutti gli altri script chiamati da Python vedano le variabili di ambiente impostate.

Se lo faccio

os.environ["DEBUSSY"] = 1`

si lamenta dicendo che 1deve essere una stringa.

Voglio anche sapere come leggere le variabili di ambiente in Python (nella parte successiva dello script) dopo averlo impostato.




Non correlato alla domanda: ho letto quella var. il nome di The Cat
ahmed

Risposte:


790

Le variabili di ambiente devono essere stringhe, quindi utilizzare

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

per impostare la variabile DEBUSSYsulla stringa 1.

Per accedere a questa variabile in un secondo momento, utilizzare semplicemente:

print(os.environ["DEBUSSY"])

I processi figlio ereditano automaticamente le variabili di ambiente del processo principale: non è richiesta alcuna azione speciale da parte dell'utente.


20
Su alcune piattaforme, la modifica di os.environ non modificherà effettivamente l'ambiente di sistema né per il processo corrente né per i processi figlio. Vedi i documenti per maggiori informazioni: docs.python.org/2/library/os.html#os.environ
Evan

8
@Evan Ci potrebbero essere alcune varianti storiche di Unix che non supportano putenv(), ma per quelle Unixen non c'è nulla che tu possa fare comunque. Anche la vecchia versione di AIX e HPUX con cui ho lavorato lo supportava. Se qualcuno è effettivamente in grado di trovare un computer che non lo supporta oggi, ho seri dubbi che saranno in grado di eseguire Python su quel computer. :)
Sven Marnach,

3
Attenzione: per citare dal riferimento di @ Evan sopra, Tali modifiche all'ambiente influenzano i sottoprocessi avviati con os.system (), popen () o fork () ed execv (). In altre parole, tieni presente che questo approccio non modificherà il modo in cui il tuo programma è in esecuzione, ma solo il modo in cui i figli del tuo programma funzionano. È vero, il tuo programma può impostare e rileggere variabili d'ambiente, ma solo dall'ambiente che configura per i suoi figli. Vedi anche: modifica l'ambiente di processo corrente . Finora non ho trovato il modo per uno script Python di modificare il suo ambiente genitore.
CODICE READ

1
@SvenMarnach è la frase "il processo figlio eredita automaticamente l'ambiente del processo genitore 'vero per shell come bash.
Krishna Oza

@darth_coder È vero per tutti i processi su sistemi operativi simili a Unix. Non conosco l'altro sistema operativo. Si noti che le variabili della shell non sono archiviate nell'ambiente a meno che non vengano esportate.
Sven Marnach,

114

Potrebbe essere necessario considerare alcuni ulteriori aspetti per la solidità del codice;

quando si memorizza una variabile con valore intero come variabile di ambiente, provare

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

quindi per il recupero, considera che per evitare errori, dovresti provare

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

eventualmente sostituire "-1" con "Non impostato"

così, per mettere tutto insieme

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
Puoi dire come impostare la variabile su una macchina Linux, il codice è lo stesso per tutte le piattaforme?
Anurag-Sharma,

2
Raramente ha senso memorizzare -1 per un numero intero mancante. Una scommessa migliore sarebbe myvar = int(os.environ.get('MYVAR')) if os.environ.get('MYVAR', '') != '' else None- in questo modo sarebbe Nessuna se non fosse fornito alcun numero
Benjamin Atkin

1
Se hai a che fare con numeri interi, un -1 ha senso. Sebbene probabilmente impostarei una variabile / costante sul valore che userei per non impostare (ad es value_not_set = '-1'.). Quindi, potresti usaredebussy = int(os.environ.get('DEBUSSY', value_not_set))
yeOldeDataSmythe

68

os.environsi comporta come un dizionario Python, quindi è possibile eseguire tutte le operazioni di dizionario comuni. Oltre alle operazioni gete setmenzionate nelle altre risposte, possiamo anche semplicemente controllare se esiste una chiave. Le chiavi e i valori devono essere memorizzati come stringhe .

Python 3

Per Python 3, dizionari di utilizzare la a parola chiave, invece di 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'

C'è una cosa importante da notare sull'uso os.environ:

Sebbene i processi figlio ereditino l'ambiente dal processo padre, di recente ho riscontrato un problema e ho capito, se hai altri script che aggiornano l'ambiente mentre il tuo script Python è in esecuzione, la chiamata di os.environnuovo non rifletterà i valori più recenti .

Estratto dai documenti :

Questa mappatura viene acquisita la prima volta che il modulo os viene importato, in genere durante l'avvio di Python come parte dell'elaborazione di site.py. Le modifiche all'ambiente apportate dopo questo periodo non si riflettono in os.environ, ad eccezione delle modifiche apportate modificando direttamente os.environ.

os.environ.data che memorizza tutte le variabili di ambiente, è un oggetto dict, che contiene tutti i valori di ambiente:

>>> type(os.environ.data)  # changed to _data since v3.2 (refer comment below)
<type 'dict'>

1
Le variabili di ambiente di un processo vengono impostate quando viene creato il processo. Eventuali modifiche apportate successivamente non influiranno sulla copia del processo della variabile di ambiente. Questo è comune a tutti i processi, non solo a Python. Inoltre, è os.environ.datastato rinominato in Python 3.2 in os.environ._data, il prefisso di sottolineatura mostra che non dovresti leggerlo direttamente. Comunque, os.environ._datanon avremo comunque valori aggiornati.
Al Sweigart,

Sì, ora capisco. Volevo condividere la mia sorpresa iniziale con gli altri che vengono a cercare. Grazie per aver sottolineato l'aggiornamento al nome della variabile dal 3.2, aggiornerà la risposta.
sisanared

21

se faccio os.environ ["DEBUSSY"] = 1, si lamenta dicendo che 1 deve essere una stringa.

Quindi fa

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

Voglio anche sapere come leggere le variabili di ambiente in Python (nella parte successiva dello script) dopo averlo impostato.

Basta usare os.environ["DEBUSSY"], come in

some_value = os.environ["DEBUSSY"]

19

impostare la variabile:

voce Metodo di assegnazione mediante chiave:

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

per ottenere o controllare se esisteva o no,

poiché os.environ è un'istanza, puoi provare ad usare l'oggetto.

Metodo 1:

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

otterrà '1'come valore di ritorno

Metodo 2:

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

Metodo 3:

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

Metodo 4:

os.environ.has_key('DEBUSSY') #last 2 methods are Boolean Return so can use for conditional statements

16

È necessario assegnare il valore di stringa alla variabile di ambiente.

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

Se vuoi leggere o stampare la variabile d'ambiente, basta usare

print os.environ["DEBUSSY"]

Queste modifiche saranno effettive solo per il processo corrente in cui è stato assegnato, non modificheranno il valore in modo permanente. I processi figlio erediteranno automaticamente l'ambiente del processo padre.

inserisci qui la descrizione dell'immagine


5
"Queste modifiche saranno effettive solo per l'attuale processo in cui è stata assegnata, non modificheranno il valore in modo permanente." Ciò ha risposto a una domanda che avevo sull'ambito di impostare una variabile ambientale.
spitfiredd,

2
Se esco dalla shell Python e il sistema operativo ambient precedentemente impostato non è più disponibile.
MeadowMuffins,

Come posso impostare una variabile d'ambiente in Windows? Ho provato set [<name>=[<value>]]ma lo rende solo per l'attuale processo in esecuzione. Quando chiudo il cmd non esiste e anche quando è aperto altri programmi non possono vederlo.
Filip

15

Che dire os.environ["DEBUSSY"] = '1'? Le variabili di ambiente sono sempre stringhe.


14

Ho cercato di aggiungere variabili di ambiente. Il mio obiettivo era quello di memorizzare alcune informazioni utente nelle variabili di sistema in modo tale da poterle utilizzare per soluzioni future, in alternativa ai file di configurazione. Tuttavia, il metodo descritto nel codice seguente non mi ha aiutato affatto.

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

Questo semplice blocco di codice funziona bene, tuttavia, queste variabili esistono all'interno dei rispettivi processi in modo tale che non le troverai nella scheda delle variabili di ambiente delle impostazioni di sistema di Windows. Praticamente il codice sopra non ha funzionato per il mio scopo. Questo problema è discusso qui: problema di salvataggio variabile

os.environ.putenv(key, value)

Un altro tentativo fallito. Quindi, finalmente, sono riuscito a salvare con successo la variabile all'interno del registro dell'ambiente windows imitando i comandi della shell di Windows racchiusi nella classe di sistema del pacchetto os. Il codice seguente descrive questo tentativo riuscito.

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

Spero che questo possa essere utile per alcuni di voi.


12

Va notato che se si tenta di impostare la variabile di ambiente su una valutazione bash , non memorizzerà ciò che ci si aspetta. Esempio:

from os import environ

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

Questo non lo valuterà come in una shell, quindi invece di ottenere /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Homecome percorso otterrai l'espressione letterale $(/usr/libexec/java_home).

Assicurati di valutarlo prima di impostare la variabile di ambiente, in questo modo:

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

È possibile utilizzare il os.environdizionario per accedere alle variabili di ambiente.

Ora, un problema che ho avuto è che se avessi cercato di utilizzare os.systemper eseguire un file batch che imposta le variabili di ambiente (utilizzando il comando SET in un file **. Bat *), non le imposterebbe davvero per il tuo ambiente Python (ma per il processo figlio creato con la os.systemfunzione). Per ottenere effettivamente le variabili impostate nell'ambiente python, uso questo script:

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

Quando si gioca con le variabili di ambiente (aggiungi / modifica / rimuovi variabili), è buona norma ripristinare lo stato precedente al completamento della funzione.

Potrebbe essere necessario qualcosa di simile al modified_environgestore del contesto descritto in questa domanda per ripristinare le variabili di ambiente.

Uso classico:

with modified_environ(DEBUSSY="1"):
    call_my_function()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.