问题:检查环境变量是否存在的良好实践是什么?
我想检查我的环境中是否存在"FOO"
Python 中的变量。为此,我正在使用os
标准库。阅读图书馆的文档后,我想出了两种实现目标的方法:
方法1:
if "FOO" in os.environ:
pass
方法2:
if os.getenv("FOO") is not None:
pass
我想知道哪种方法是好的/首选条件,以及为什么。
回答 0
使用第一个;它直接尝试检查是否在中定义了某些内容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")
如果您确实想用可能获得的价值做某事。
回答 1
两种解决方案都有一种情况,这取决于您要根据环境变量的存在来执行什么操作。
情况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)
回答 2
为了安全起见
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'))"
回答 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))
回答 4
我的评论可能与给定的标签无关。但是,我是从搜索中转到此页面的。我一直在寻找R中的类似支票,并在@hugovdbeg帖子的帮助下提出了以下内容。我希望这对在R中寻求类似解决方案的人有所帮助
'USERNAME' %in% names(Sys.getenv())