Яка хороша практика перевірити, чи існує змінна середовище чи ні?


130

Я хочу перевірити своє середовище на наявність змінної, скажімо "FOO", в Python. Для цього я використовую osстандартну бібліотеку. Прочитавши документацію бібліотеки, я з’ясував 2 способи досягнення своєї мети:

Спосіб 1:

if "FOO" in os.environ:
    pass

Спосіб 2:

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

Я хотів би знати, який метод, якщо такий є, хороший / кращий умовний і чому.


Це в першу чергу засноване на думці. Обидва служать одній цілі. Я віддаю перевагу способу 1, оскільки він чистіший
Moinuddin Quadri

1
Я не можу сказати, що в ньому є щось. Виберіть одну (переверніть монету?) Та переоцініть пізніше, якщо виявиться, що вона не працює. Відверто кажучи, я вважаю, що ви витратили більше часу на введення цього питання, ніж заощадили б будь-який спосіб!
jonrsharpe

1
@Ayoub: Я думаю, ви забули побачити питання "Яка хороша практика перевірити, чи існує змінна середовища в Python чи ні?"
Moinuddin Quadri

1
На основі думки. Синтаксис першого способу служить краще, оскільки ви запитуєте, чи fooє в оточенні, а не якщо ви шукаєте fooрезультатів у Noneзначеннях.
Уріель

1
Але такий спосіб може бути не очевидним, якщо ви не голландці ...
jonrsharpe

Відповіді:


168

Використовуйте перший; він безпосередньо намагається перевірити, чи визначено щось у environ. Хоча друга форма працює однаково добре, вона не вистачає семантично, оскільки ви отримуєте значення назад, якщо воно існує, і використовуєте його лише для порівняння.

Ви намагаєтеся зрозуміти, чи є щось у цьому environ , чому б вам вдалося просто порівняти його, а потім відкинути ?

Саме це і getenvробить:

Отримайте змінну середовища , поверніться, Noneякщо її не існує. Необов'язковий другий аргумент може вказати альтернативний за замовчуванням.

(це також означає, що ваш чек може бути просто if getenv("FOO"))

ви не хочете отримати його , ви хочете перевірити його існування.

Так чи інакше, getenvце просто обгортка навколо, environ.getале ви не бачите людей, які перевіряють на членство у картах із:

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

Для підведення підсумків використовуйте:

if "FOO" in os.environ:
    pass

якщо ви просто хочете перевірити наявність, тоді використовуйте, getenv("FOO")якщо ви насправді хочете зробити щось із значенням, яке ви могли б отримати.


2
Дякуємо за ваше пояснення. Я буду мати це на увазі.
Kshitij Saraogi

29

Існує випадок для будь-якого рішення, залежно від того, що ви хочете зробити умовним для існування змінної середовища.

Випадок 1

Коли ви хочете вживати різних дій суто на основі існування змінної середовища, не піклуючись про її значення, перше рішення - найкраща практика. Він коротко описує те, на що ви тестуєте: "FOO" у списку змінних середовища.

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

Випадок 2

Коли ви хочете встановити значення за замовчуванням, якщо значення не визначене в змінних оточення, друге рішення насправді корисне, хоча не у формі, яку ви його написали:

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

чи, можливо,

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

Зауважте, що якщо у вас є кілька варіантів вашої програми, ви, можливо, захочете вивчити ChainMap, що дозволяє об'єднати кілька диктовок на основі клавіш. Приклад цього є в ChainMapдокументації:

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

15

Для безпечного використання

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

Кутовий випадок із наведеними вище відповідями - це коли змінна середовища встановлена, але порожня

Для цього ви отримаєте особливий випадок

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

або

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

Щоб цього уникнути, просто використовуйте or

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

Тоді ви отримуєте

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

Коли у нас є порожні змінні середовища?

Ви забули встановити значення у .envфайлі

# .env
FOO=

або експортується як

$ export FOO=

або забув його встановити settings.py

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

Оновлення: якщо ви сумніваєтесь, перегляньте ці однолистові

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

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

Підпис для getenv - це def getenv(key, default=None):так, якщо так, це повинно дозволяти за замовчуванням проти або синтаксис на початку
Кріс Маккі

@Chris McKee спробуйте це>>> import os; os.environ['FOO'] = ''; print(os.getenv('FOO', 'bar'))
Левон

Підпис методу омани 😜
Кріс Маккі

1
@Chris McKee, ще один приклад$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"
Левон

3

Якщо ви хочете перевірити, чи не встановлено кілька змінних env, ви можете зробити наступне:

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

Мій коментар може не стосуватися наведених тегів. Однак мене привели на цю сторінку з мого пошуку. Я шукав подібну перевірку в R, і я придумав наступне за допомогою повідомлення @hugovdbeg. Я сподіваюся, що це буде корисно для того, хто шукає подібне рішення в R

'USERNAME' %in% names(Sys.getenv())
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.