检查环境变量是否存在的良好实践是什么?


130

我想检查我的环境中是否存在"FOO"Python 中的变量。为此,我正在使用os标准库。阅读图书馆的文档后,我想出了两种实现目标的方法:

方法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
基于意见。方法1的语法效果更好,因为您询问是否foo在env var中,而不是是否fooNone值中寻找结果。
Uriel's

1
但是,除非您是荷兰人,否则这种方式可能并不明显...
jonrsharpe

Answers:


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

29

两种解决方案都有一种情况,这取决于您要根据环境变量的存在来执行什么操作。

情况1

如果您想纯粹基于环境变量的存在而采取不同的措施而又不关心其价值,那么第一个解决方案就是最佳实践。它简要描述了您要测试的内容:环境变量列表中的'FOO'。

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

情况二

如果您想在环境变量中未定义该值的情况下设置默认值,则第二个解决方案实际上很有用,尽管它不是您编写的形式:

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):应该是这样,如果允许的话,一开始应该允许默认vs或or语法
克里斯·麦基

@克里斯·麦基(Chris McKee)尝试>>> import os; os.environ['FOO'] = ''; print(os.getenv('FOO', 'bar'))
莱文(Levon)

误导性方法签名😜–
克里斯·麦基

1
@克里斯·麦克基(Chris McKee),另一个例子$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"
冯(Levon)

3

如果您要检查是否未设置多个环境变量,可以执行以下操作:

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())
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.