Différence entre os.getenv et os.environ.get

159

Y a-t-il une différence entre les deux approches?

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

Ils semblent avoir exactement la même fonctionnalité.

André Staltz
la source

Réponses:

60

Une différence observée (Python27):

os.environlève une exception si la variable d'environnement n'existe pas. os.getenvne lève pas d'exception, mais renvoie None

giwyni
la source
119
L'OP demande os.environ.get()quels retours None(sauf indication contraire) et ne lève jamais d'exception si env. var. n'existe pas. Vos choses déroutantes avec l'utilisation os.environ['TERM']qui n'est pas l'objet de la question.
Anthon
2
La question du PO porte sur os.environ.get()vs os.getenv()mais le corps inclut également os.environvs os.environ.get()donc cette réponse est correcte au moins à certains égards - incomplète, mais correcte.
FKEinternet
3
Cette réponse incorrecte et trompeuse aurait dû recevoir des votes négatifs. La réponse suivante est la bonne.
RayLuo
80

Voir ce fil associé . Fondamentalement, os.environse trouve lors de l'importation et os.getenvest un wrapper pour os.environ.get, au moins en CPython.

EDIT: Pour répondre à un commentaire, en CPython, os.getenvest essentiellement un raccourci vers os.environ.get; puisque os.environest chargé à l'importation de os, et alors seulement, il en va de même pour os.getenv.

W. Conrad Walden
la source
1
En effet, c'est, selon la doc officielle: docs.python.org/3/library/os.html
ivanleoncz
1
Du fil de discussion lié lié: «la principale raison d'utiliser os.getenv()[...] est lorsque vous voulez avoir une valeur par défaut renvoyée quand un nom de variable d'environnement n'est pas trouvé dans os.environles clés de plutôt que d'avoir un KeyErrorou quoi que ce soit, et vous voulez enregistrer quelques caractères. "
mindthief
35

En Python 2.7 avec 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

Nous pouvons donc conclure qu'il ne os.getenvs'agit que d'un simple wrapper os.environ.get.

zoulou
la source
16

Bien qu'il n'y ait pas de différence fonctionnelle entre os.environ.getet os.getenv, il existe une énorme différence entre os.putenvet définir les entrées sur os.environ. os.putenvest cassé , vous devriez donc utiliser par défaut os.environ.getsimplement pour éviter que la manière os.getenvvous encourage à utiliser os.putenvpour la symétrie.

os.putenvmodifie les variables d'environnement OS-niveau réel, mais d'une manière qui ne se présente pas à travers os.getenv, os.environou de toute autre manière stdlib d'inspecter les variables d'environnement:

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

Vous devrez probablement faire un appel ctypes au niveau C getenvpour voir les variables d'environnement réelles après l'appel os.putenv. (Lancer un sous-processus shell et lui demander ses variables d'environnement peut également fonctionner, si vous faites très attention à l'échappement et --norc/ --noprofile/ à tout ce que vous devez faire pour éviter la configuration de démarrage, mais cela semble beaucoup plus difficile à faire.)

user2357112 prend en charge Monica
la source
2

En plus des réponses ci-dessus:

$ 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
la source
Avec quelle version de Python avez-vous testé. Sur 3.7.2, os.getenvc'est juste un wrapper pour os.environ.get, donc je reçois une surcharge très minime.
Preslav Rachev
C'était la 3.7.1 sur macOS Mojave. Les horaires étaient assez cohérents.
fredrik
@PreslavRachev minimal ou non c'est un appel de fonction supplémentaire, donc il y a une surcharge. Cela étant dit, vous n'avez probablement pas besoin de récupérer les variables env au milieu de votre boucle interne.
pmav99
7
Totalement hors de propos. Micro-optimisation d'un seul appel de fonction ... De toute façon, toute application ne doit lire l'environnement qu'au bootstrap, ce qui rend cela encore plus inutile.
Victor Schröder
1
BTW, usecest une microseconde dans timeit. La différence trouvée dans ce micro-benchmarking était de 0,18 microsecondes ...
Victor Schröder