Cómo establecer variables de entorno en Python

658

Necesito establecer algunas variables de entorno en la secuencia de comandos de python y quiero que todas las demás secuencias de comandos a las que se llama desde python vean las variables de entorno establecidas.

Si lo hago

os.environ["DEBUSSY"] = 1`

se queja diciendo que 1tiene que ser una cadena.

También quiero saber cómo leer las variables de entorno en python (en la parte posterior del script) una vez que lo configuro.

prahallada
fuente
también relacionado: youtu.be/ScyxIfOuSXs?t=61
Yannic Hamann
Sin relación con la pregunta: leí que la var. nombre como The Cat
ahmed

Respuestas:

790

Las variables de entorno deben ser cadenas, así que use

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

para establecer la variable DEBUSSYa la cadena 1.

Para acceder a esta variable más tarde, simplemente use:

print(os.environ["DEBUSSY"])

Los procesos secundarios heredan automáticamente las variables de entorno del proceso primario; no se requiere ninguna acción especial de su parte.

Sven Marnach
fuente
20
En algunas plataformas, la modificación de os.environ no modificará el entorno del sistema ni para el proceso actual ni para los procesos secundarios. Consulte los documentos para obtener más información: docs.python.org/2/library/os.html#os.environ
Evan
8
@Evan Puede haber algunas variantes históricas de Unix que no son compatibles putenv(), pero para esos Unixen no hay nada que pueda hacer de todos modos. Incluso la versión anterior de AIX y HPUX con la que trabajé lo admitía. Si alguien puede encontrar una computadora que no lo admite hoy, tengo serias dudas de que pueda ejecutar Python en esa computadora. :)
Sven Marnach
3
Precaución: para citar la referencia de @ Evan anterior, dichos cambios en el entorno afectan a los subprocesos iniciados con os.system (), popen () o fork () y execv (). En otras palabras, tenga en cuenta que este enfoque no modificará la forma en que se ejecuta su programa, solo la forma en que se ejecutan los hijos de su programa. Es cierto que su programa puede establecer y leer variables de entorno, pero solo desde el entorno que configura para sus hijos. Ver también: cambiar el entorno actual del proceso . Hasta ahora no he encontrado una manera para que un script de Python modifique su entorno principal.
CÓDIGO DE LECTURA
1
@SvenMarnach es la declaración "el proceso hijo hereda automáticamente el entorno del proceso padre" verdadero para shell como bash.
Krishna Oza
@darth_coder Es cierto para todos los procesos en sistemas operativos tipo Unix. No sé sobre el otro sistema operativo. Tenga en cuenta que las variables de shell no se almacenan en el entorno a menos que las exporte.
Sven Marnach
114

Es posible que deba considerar algunos aspectos adicionales para la solidez del código;

cuando esté almacenando una variable de valor entero como una variable de entorno, intente

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

luego para la recuperación, considere que para evitar errores, debe intentar

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

posiblemente sustituya '-1' por 'No establecido'

entonces, para poner todo junto

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)
marca
fuente
3
¿Puedes decir cómo establecería la variable en una máquina Linux, es el mismo código para todas las plataformas?
Anurag-Sharma
2
Rara vez tiene sentido almacenar -1 para un entero perdido. Una mejor apuesta sería myvar = int(os.environ.get('MYVAR')) if os.environ.get('MYVAR', '') != '' else None: de esa manera sería Ninguno si no se proporcionara ningún número
Benjamin Atkin
1
Si se trata de enteros, un -1 tiene sentido. Aunque probablemente establecería una variable / constante en el valor que usaría para no establecer (por ejemplo, value_not_set = '-1'). Entonces, podrías usardebussy = int(os.environ.get('DEBUSSY', value_not_set))
yeOldeDataSmythe el
68

os.environse comporta como un diccionario de python, por lo que se pueden realizar todas las operaciones comunes del diccionario. Además de las operaciones gety setmencionadas en las otras respuestas, también podemos simplemente verificar si existe una clave. Las claves y los valores deben almacenarse como cadenas .

Python 3

Para python 3, los diccionarios usan la palabra clave in en lugar de 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'

Hay una cosa importante a tener en cuenta sobre el uso os.environ:

Aunque los procesos secundarios heredan el entorno del proceso principal, me encontré con un problema recientemente y descubrí que si tiene otras secuencias de comandos que actualizan el entorno mientras se ejecuta su secuencia de comandos de Python, os.environvolver a llamar no reflejará los últimos valores .

Extracto de los documentos :

Esta asignación se captura la primera vez que se importa el módulo os, generalmente durante el inicio de Python como parte del procesamiento site.py. Los cambios en el entorno realizados después de este tiempo no se reflejan en os.environ, excepto los cambios realizados modificando os.environ directamente.

os.environ.data que almacena todas las variables de entorno, es un objeto dict, que contiene todos los valores del entorno:

>>> type(os.environ.data)  # changed to _data since v3.2 (refer comment below)
<type 'dict'>
sisanared
fuente
1
Las variables de entorno de un proceso se establecen cuando se crea el proceso. Cualquier cambio realizado después de esto no afectará la propia copia del proceso de la variable de entorno. Esto es común a todos los procesos, no solo a Python. Además, os.environ.datase renombró en Python 3.2 a os.environ._data, el prefijo de subrayado que muestra que no debe leerlo directamente. De todos modos, os.environ._datano tendrá valores actualizados de todos modos.
Al Sweigart
Sí, ahora entiendo. Quería compartir mi sorpresa inicial con otros que vienen a buscar. Gracias por señalar la actualización del nombre de la variable desde 3.2, actualizará la respuesta.
Sisanared
21

si hago os.environ ["DEBUSSY"] = 1, se queja diciendo que 1 tiene que ser una cadena.

Entonces hazlo

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

También quiero saber cómo leer las variables de entorno en python (en la parte posterior del script) una vez que lo configuro.

Solo use os.environ["DEBUSSY"], como en

some_value = os.environ["DEBUSSY"]
Jim Brissom
fuente
19

establecer variable:

Método de asignación de elementos utilizando la clave:

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

para obtener o verificar si existió o no,

dado que os.environ es una instancia, puede intentar de manera objetiva .

Método 1:

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

obtendrá '1'como valor de retorno

Método 2:

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

Método 3:

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

Método 4:

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

Debe asignar un valor de cadena a la variable de entorno.

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

Si desea leer o imprimir la variable de entorno simplemente use

print os.environ["DEBUSSY"]

Estos cambios serán efectivos solo para el proceso actual donde fue asignado, no cambiará el valor permanentemente. Los procesos secundarios heredarán automáticamente el entorno del proceso principal.

ingrese la descripción de la imagen aquí

RejeeshChandran
fuente
55
"Estos cambios serán efectivos solo para el proceso actual donde fue asignado, no cambiará el valor de forma permanente". Esto respondió una pregunta que tenía sobre el alcance de establecer una variable de entorno.
spitfiredd
2
Si salgo del shell de Python, y el entorno OS establecido anteriormente desaparece.
MeadowMuffins
¿Cómo configuro una variable de entorno en Windows? Lo intenté set [<name>=[<value>]]pero solo lo hace para el proceso de ejecución actual. Cuando cierro el cmd no existe e incluso cuando está abierto, otros programas no pueden verlo.
Filip
15

¿Qué hay de os.environ["DEBUSSY"] = '1'? Las variables de entorno son siempre cadenas.

ThiefMaster
fuente
14

He estado tratando de agregar variables de entorno. Mi objetivo era almacenar cierta información del usuario en las variables del sistema, de modo que pueda usar esas variables para futuras soluciones, como alternativa a los archivos de configuración. Sin embargo, el método descrito en el código a continuación no me ayudó en absoluto.

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

Este bloque de código simple funciona bien, sin embargo, estas variables existen dentro de los procesos respectivos, de modo que no las encontrará en la pestaña de variables de entorno de la configuración del sistema de Windows. El código más arriba mencionado no sirvió para mi propósito. Este problema se discute aquí: problema de guardar variable

os.environ.putenv(key, value)

Otro intento fallido. Entonces, finalmente, logré guardar la variable con éxito dentro del registro del entorno de la ventana imitando los comandos de shell de Windows envueltos dentro de la clase de sistema del paquete os. El siguiente código describe este intento exitoso.

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

Espero que esto sea útil para algunos de ustedes.

Sourabh Desai
fuente
12

Cabe señalar que si intenta establecer la variable de entorno en una evaluación bash , no almacenará lo que espera. Ejemplo:

from os import environ

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

Esto no lo evaluará como lo hace en un shell, por lo que en lugar de obtener /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Homecomo una ruta obtendrá la expresión literal $(/usr/libexec/java_home).

Asegúrese de evaluarlo antes de configurar la variable de entorno, así:

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

Puede usar el os.environdiccionario para acceder a sus variables de entorno.

Ahora, un problema que tuve es que si intentara usar os.systempara ejecutar un archivo por lotes que establezca sus variables de entorno (usando el comando SET en un archivo **. Bat *) realmente no las establecería para su entorno de Python (sino para El proceso hijo que se crea con la os.systemfunción). Para obtener realmente las variables establecidas en el entorno de Python, utilizo este 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
Ricardo Alejos
fuente
9

Cuando juegas con variables de entorno (agregar / modificar / eliminar variables), una buena práctica es restaurar el estado anterior al finalizar la función.

Es posible que necesite algo como el modified_environadministrador de contexto que se describe en esta pregunta para restaurar las variables de entorno.

Uso clásico:

with modified_environ(DEBUSSY="1"):
    call_my_function()
Laurent LAPORTE
fuente