Diferencia entre os.getenv y os.environ.get

159

¿Hay alguna diferencia entre ambos enfoques?

>>> os.getenv('TERM')
'xterm'
>>> os.environ.get('TERM')
'xterm'

>>> os.getenv('FOOBAR', "not found") == "not found"
True
>>> os.environ.get('FOOBAR', "not found") == "not found"
True

Parecen tener exactamente la misma funcionalidad.

André Staltz
fuente

Respuestas:

60

Una diferencia observada (Python27):

os.environplantea una excepción si la variable ambiental no existe. os.getenvno genera una excepción, pero devuelve Ninguno

giwyni
fuente
119
El OP pregunta os.environ.get()qué retornos None(a menos que se especifique lo contrario) y nunca genera una excepción si el env. var. no existe Sus cosas confusas con el uso os.environ['TERM']que no es de lo que se trata la pregunta.
Anthon
2
La pregunta del OP se refiere a os.environ.get()vs, os.getenv()pero el cuerpo también incluye os.environvs, os.environ.get()por lo que esta respuesta es correcta al menos en algunos aspectos: incompleta, pero correcta.
FKEinternet 01 de
3
Esta respuesta incorrecta y engañosa debería haber recibido votos negativos. La siguiente respuesta es la correcta.
RayLuo
80

Ver este hilo relacionado . Básicamente, os.environse encuentra en la importación, y os.getenves un contenedor para os.environ.get, al menos en CPython.

EDITAR: Para responder a un comentario, en CPython, os.getenves básicamente un acceso directo a os.environ.get; ya que os.environse carga en la importación de os, y solo entonces, lo mismo vale para os.getenv.

W. Conrad Walden
fuente
1
De hecho, según el documento oficial: docs.python.org/3/library/os.html
ivanleoncz
1
Desde el hilo relacionado vinculado: "la razón principal para usar os.getenv()[...] es cuando desea que se devuelva un valor predeterminado cuando no se encuentra un nombre de variable de entorno en os.environlas claves de las teclas en lugar de tener un KeyErroro lo que sea lanzado, y usted querer guardar algunos caracteres ".
mindthief
35

En Python 2.7 con iPython:

>>> import os
>>> os.getenv??
Signature: os.getenv(key, default=None)
Source:
def getenv(key, default=None):
    """Get an environment variable, return None if it doesn't exist.
    The optional second argument can specify an alternate default."""
    return environ.get(key, default)
File:      ~/venv/lib/python2.7/os.py
Type:      function

Por lo tanto, podemos concluir que os.getenves solo una simple envoltura os.environ.get.

zulú
fuente
16

Si bien no existe una diferencia funcional entre os.environ.gety os.getenv, existe una gran diferencia entre os.putenvy establecer entradas en os.environ. os.putenvestá roto , por lo que debe usar os.environ.getsimplemente para evitar la forma en que lo os.getenvalienta a usar os.putenvpara la simetría.

os.putenvcambia las variables de entorno del sistema operativo de nivel, pero de una manera que no se presenta a través de os.getenv, os.environo de cualquier otra manera stdlib de inspeccionar las variables de entorno:

>>> import os
>>> os.environ['asdf'] = 'fdsa'
>>> os.environ['asdf']
'fdsa'
>>> os.putenv('aaaa', 'bbbb')
>>> os.getenv('aaaa')
>>> os.environ.get('aaaa')

Probablemente tendría que hacer una llamada de ctypes al nivel C getenvpara ver las variables de entorno reales después de llamar os.putenv. (Iniciar un subproceso de shell y preguntarle por sus variables de entorno también podría funcionar, si tiene mucho cuidado con el escape y --norc/ --noprofileo cualquier otra cosa que necesite hacer para evitar la configuración de inicio, pero parece mucho más difícil hacerlo bien).

user2357112 es compatible con Monica
fuente
2

Además de las respuestas anteriores:

$ python3 -m timeit -s 'import os' 'os.environ.get("TERM_PROGRAM")'
200000 loops, best of 5: 1.65 usec per loop

$ python3 -m timeit -s 'import os' 'os.getenv("TERM_PROGRAM")'
200000 loops, best of 5: 1.83 usec per loop
fredrik
fuente
¿Con qué versión de Python has probado? En 3.7.2, os.getenves solo un contenedor para os.environ.get, por lo que obtengo una sobrecarga muy mínima.
Preslav Rachev el
Eso fue 3.7.1 en macOS Mojave. Los tiempos fueron bastante consistentes.
fredrik
@PreslavRachev mínimo o no es una llamada de función adicional, por lo que hay algunos gastos generales. Dicho esto, probablemente no necesite recuperar las variables env en el medio de su bucle interno.
pmav99
77
Totalmente irrelevante. Micro-optimización de una sola llamada de función ... De todos modos, cualquier aplicación debería leer el entorno solo en bootstrap, lo que lo hace aún más irrelevante.
Victor Schröder
1
Por cierto, useces un microsegundo en timeit. La diferencia encontrada en este micro-benchmarking fue de 0.18 microsegundos ...
Victor Schröder el