¿Cuál es una buena práctica para verificar si existe o no una variable ambiental?

130

Quiero verificar en mi entorno la existencia de una variable, por ejemplo "FOO", en Python. Para este propósito, estoy usando la osbiblioteca estándar. Después de leer la documentación de la biblioteca, descubrí 2 formas de lograr mi objetivo:

Método 1:

if "FOO" in os.environ:
    pass

Método 2:

if os.getenv("FOO") is not None:
    pass

Me gustaría saber qué método, si alguno, es un condicional bueno / preferido y por qué.

Kshitij Saraogi
fuente
Se basa principalmente en la opinión. Ambos tienen el mismo propósito. Preferiré el método 1, ya que es más limpio
Moinuddin Quadri
1
No puedo decir que haya nada en eso. Elija una (¿lanzar una moneda?) Y reevalúe más tarde si resulta que no funciona. Francamente, creo que ha pasado más tiempo escribiendo esta pregunta de lo que ahorraría de cualquier manera.
jonrsharpe
1
@Ayoub: Creo que olvidó ver la pregunta "¿Cuál es una buena práctica para verificar si existe una variable ambiental o no en Python?"
Moinuddin Quadri
1
Opinión basada. La sintaxis del método 1 sirve mejor, ya que se pregunta si fooestá en el entorno, no si se buscan fooresultados en Nonevalores.
Uriel
1
Pero ese camino podría no ser obvio, a menos que sea holandés ...
jonrsharpe

Respuestas:

168

Usa el primero; trata directamente de verificar si algo está definido en environ. Aunque la segunda forma funciona igualmente bien, carece semánticamente ya que obtiene un valor de regreso si existe y solo lo usa para una comparación.

Usted está tratando de ver si algo está presente en environ , ¿por qué tener sólo para comparar y luego tirar a la basura ?

Eso es exactamente lo que getenvhace:

Obtenga una variable de entorno , regrese Nonesi no existe. El segundo argumento opcional puede especificar un valor predeterminado alternativo.

(esto también significa que su cheque podría ser if getenv("FOO"))

no quieres obtenerlo , quieres verificar si existe.

De cualquier manera, getenves solo una envoltura, environ.getpero no ves a las personas que buscan membresía en las asignaciones con:

from os import environ
if environ.get('Foo') is not None:

Para resumir, use:

if "FOO" in os.environ:
    pass

si solo desea verificar la existencia, mientras lo usa, getenv("FOO")si realmente desea hacer algo con el valor que podría obtener.

Dimitris Fasarakis Hilliard
fuente
2
Gracias por tu explicación. Voy a tener esto en cuenta.
Kshitij Saraogi
29

Existe un caso para cualquiera de las soluciones, dependiendo de lo que desee hacer condicional a la existencia de la variable de entorno.

Caso 1

Cuando desee realizar diferentes acciones basadas únicamente en la existencia de la variable de entorno, sin importar su valor, la primera solución es la mejor práctica. Describe sucintamente para qué se prueba: es 'FOO' en la lista de variables de entorno.

if 'KITTEN_ALLERGY' in os.environ:
    buy_puppy()
else:
    buy_kitten()

Caso 2

Cuando desee establecer un valor predeterminado si el valor no está definido en las variables de entorno, la segunda solución es realmente útil, aunque no en la forma en que la escribió:

server = os.getenv('MY_CAT_STREAMS', 'youtube.com')

o quizás

server = os.environ.get('MY_CAT_STREAMS', 'youtube.com')

Tenga en cuenta que si tiene varias opciones para su aplicación, es posible que desee analizar ChainMap, lo que permite combinar varios dictados basados ​​en claves. Hay un ejemplo de esto en la ChainMapdocumentación:

[...]
combined = ChainMap(command_line_args, os.environ, defaults)
hugovdberg
fuente
15

Para estar seguro use

os.getenv('FOO') or 'bar'

Un caso de esquina con las respuestas anteriores es cuando la variable de entorno se establece pero está vacía

Para este caso especial obtienes

print(os.getenv('FOO', 'bar'))
# prints new line - though you expected `bar`

o

if "FOO" in os.environ:
    print("FOO is here")
# prints FOO is here - however its not

Para evitar esto solo use or

os.getenv('FOO') or 'bar'

Entonces obtienes

print(os.getenv('FOO') or 'bar')
# bar

¿Cuándo tenemos variables de entorno vacías?

Olvidó establecer el valor en el .envarchivo

# .env
FOO=

o exportado como

$ export FOO=

u olvidé configurarlo settings.py

# settings.py
os.environ['FOO'] = ''

Actualización: si tiene dudas, consulte estas frases.

>>> import os; os.environ['FOO'] = ''; print(os.getenv('FOO', 'bar'))

$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"
Levon
fuente
La firma de getenv es def getenv(key, default=None):así, si es así, debería permitir una sintaxis predeterminada frente a la o al principio
Chris McKee
@ Chris McKee intenta esto>>> import os; os.environ['FOO'] = ''; print(os.getenv('FOO', 'bar'))
Levon
Firma del método engañoso 😜
Chris McKee
1
@ Chris McKee, otro ejemplo$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"
Levon
3

En caso de que desee comprobar si no se establecen múltiples variables env, puede hacer lo siguiente:

import os

MANDATORY_ENV_VARS = ["FOO", "BAR"]

for var in MANDATORY_ENV_VARS:
    if var not in os.environ:
        raise EnvironmentError("Failed because {} is not set.".format(var))
vhamon
fuente
-1

Mi comentario podría no ser relevante para las etiquetas dadas. Sin embargo, fui llevado a esta página desde mi búsqueda. Estaba buscando un control similar en R y se me ocurrió lo siguiente con la ayuda de @hugovdbeg post. Espero que sea útil para alguien que está buscando una solución similar en R

'USERNAME' %in% names(Sys.getenv())
sveer
fuente