Was ist eine gute Praxis, um zu überprüfen, ob eine Umgebungsvariable vorhanden ist oder nicht?


129

Ich möchte meine Umgebung auf das Vorhandensein einer Variablen überprüfen "FOO", beispielsweise in Python. Zu diesem Zweck verwende ich die osStandardbibliothek. Nachdem ich die Dokumentation der Bibliothek gelesen habe, habe ich zwei Möglichkeiten gefunden, um mein Ziel zu erreichen:

Methode 1:

if "FOO" in os.environ:
    pass

Methode 2:

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

Ich würde gerne wissen, welche Methode eine gute / bevorzugte Bedingung ist und warum.


Es basiert hauptsächlich auf Meinungen. Beide dienen demselben Zweck. Ich werde Methode 1 bevorzugen, da es sauberer ist
Moinuddin Quadri

1
Ich kann nicht sagen, dass etwas drin ist. Wählen Sie eine aus (werfen Sie eine Münze?) Und bewerten Sie sie später erneut, wenn sich herausstellt, dass sie nicht funktioniert. Ehrlich gesagt denke ich, dass Sie mehr Zeit damit verbracht haben, diese Frage zu tippen, als Sie so oder so sparen würden!
Jonrsharpe

1
@ Ayoub: Ich denke, Sie haben vergessen, die Frage "Was ist eine gute Vorgehensweise, um zu überprüfen, ob eine Umgebungsvariable in Python vorhanden ist oder nicht?" Zu sehen.
Moinuddin Quadri

1
Meinungsbasiert. Die Syntax von Methode 1 ist besser foogeeignet , da Sie fragen, ob sie in den env-Variablen enthalten ist, und nicht, ob Sie nach fooErgebnissen in NoneWerten suchen .
Uriel

1
Aber dieser Weg könnte nicht offensichtlich sein, es sei denn, Sie sind Holländer ...
Jonrsharpe

Antworten:


168

Verwenden Sie die erste; es versucht direkt zu überprüfen, ob etwas in definiert ist environ. Obwohl die zweite Form genauso gut funktioniert, fehlt sie semantisch, da Sie einen Wert zurückerhalten, wenn er vorhanden ist, und ihn nur für einen Vergleich verwenden.

Sie versuchen , zu sehen , ob etwas vorhanden ist in environ , warum würden Sie bekommen nur vergleichen sie und dann werfen Sie es weg ?

Genau das getenvmacht:

Holen Sie sich eine Umgebungsvariable und geben NoneSie sie zurück, wenn sie nicht vorhanden ist. Das optionale zweite Argument kann einen alternativen Standard angeben.

(Dies bedeutet auch, dass Ihr Scheck nur sein könnte if getenv("FOO"))

du willst es nicht bekommen , du willst überprüfen, ob es existiert.

In beiden Fällen getenvhandelt es sich nur um einen Wrapper, environ.getaber Sie sehen keine Personen, die in Zuordnungen nach Mitgliedschaft suchen, mit:

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

Um es zusammenzufassen, verwenden Sie:

if "FOO" in os.environ:
    pass

Wenn Sie nur nach der Existenz getenv("FOO")suchen möchten , verwenden Sie diese Option , wenn Sie tatsächlich etwas mit dem Wert tun möchten, den Sie möglicherweise erhalten.


2
Danke für Ihre Erklärung. Ich werde das im Hinterkopf behalten.
Kshitij Saraogi

28

Es gibt einen Fall für jede Lösung, abhängig davon, was Sie tun möchten, abhängig von der Existenz der Umgebungsvariablen.

Fall 1

Wenn Sie verschiedene Aktionen ausführen möchten, die ausschließlich auf der Existenz der Umgebungsvariablen basieren, ohne auf deren Wert zu achten, ist die erste Lösung die beste Vorgehensweise. Es beschreibt kurz und bündig, worauf Sie testen: ist 'FOO' in der Liste der Umgebungsvariablen.

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

Fall 2

Wenn Sie einen Standardwert festlegen möchten, wenn der Wert nicht in den Umgebungsvariablen definiert ist, ist die zweite Lösung tatsächlich nützlich, jedoch nicht in der Form, in der Sie sie geschrieben haben:

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

oder vielleicht

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

Beachten Sie, dass Sie möglicherweise mehrere Optionen für Ihre Anwendung prüfen möchten, um ChainMapmehrere Diktate basierend auf Schlüsseln zusammenzuführen. Ein Beispiel hierfür finden Sie in der ChainMapDokumentation:

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

15

Um auf der sicheren Seite zu sein

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

Ein Eckfall mit den obigen Antworten ist, wenn die Umgebungsvariable gesetzt ist, aber leer ist

Für diesen Sonderfall bekommen Sie

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

oder

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

Um dies zu vermeiden, verwenden Sie einfach or

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

Dann bekommst du

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

Wann haben wir leere Umgebungsvariablen?

Sie haben vergessen, den Wert in der .envDatei festzulegen

# .env
FOO=

oder exportiert als

$ export FOO=

oder vergessen, es einzustellen settings.py

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

Update: Im Zweifelsfall sehen Sie sich diese Einzeiler an

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

$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"

Die Signatur für getenv ist def getenv(key, default=None):so, wenn ja, dass ein Standard gegen die oder Syntax am Anfang erlaubt sein sollte
Chris McKee

@ Chris McKee versuchen Sie dies>>> import os; os.environ['FOO'] = ''; print(os.getenv('FOO', 'bar'))
Levon

Irreführende Methodensignatur 😜
Chris McKee

1
@ Chris McKee, ein weiteres Beispiel$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"
Levon

3

Wenn Sie überprüfen möchten, ob nicht mehrere env-Variablen festgelegt sind, können Sie Folgendes tun:

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

-1

Mein Kommentar ist möglicherweise nicht relevant für die angegebenen Tags. Ich wurde jedoch von meiner Suche zu dieser Seite geführt. Ich suchte nach einem ähnlichen Check in R und kam mit Hilfe des @ hugovdbeg-Beitrags auf Folgendes. Ich hoffe, es wäre hilfreich für jemanden, der nach einer ähnlichen Lösung in R sucht

'USERNAME' %in% names(Sys.getenv())
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.