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

Ksh*_*ogi 96 python if-statement environment-variables python-2.7 python-3.x

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

方法1:

if "FOO" in os.environ:
    pass
Run Code Online (Sandbox Code Playgroud)

方法2:

if os.getenv("FOO") is not None:
    pass
Run Code Online (Sandbox Code Playgroud)

我想知道哪种方法(如果有的话)是好的/首选条件以及为什么.

Jim*_*ard 126

使用第一个; 它直接尝试检查是否定义了某些内容environ.虽然第二种形式同样有效,但它缺乏语义,因为如果它存在并且将其用于比较,则返回值.

你想看看是否有存在 environ,为什么你会得到只是为了进行比较,然后折腾它扔掉

这正是getenv:

获取环境变量,None如果不存在则返回.可选的第二个参数可以指定备用默认值.

(这也意味着你可以检查if getenv("FOO"))

你不想得到它,你想检查它的存在.

无论哪种方式,getenv只是一个包装,environ.get但你没有看到人们检查映射的成员资格:

from os import environ
if environ.get('Foo') is not None:
Run Code Online (Sandbox Code Playgroud)

总结一下,使用:

if "FOO" in os.environ:
    pass
Run Code Online (Sandbox Code Playgroud)

如果你只想检查是否存在,getenv("FOO")那么,如果你真的想要用你可能获得的价值做某事,请使用.

  • 谢谢你的解释.我会记住这一点. (2认同)

hug*_*erg 19

两种解决方案都有一种情况,具体取决于您希望以环境变量的存在为条件.

情况1

当你想纯粹基于环境变量的存在而采取不同的行动时,不考虑其价值,第一种解决方案是最佳实践.它简洁地描述了您测试的内容:环境变量列表中的"FOO".

if 'KITTEN_ALLERGY' in os.environ:
    buy_puppy()
else:
    buy_kitten()
Run Code Online (Sandbox Code Playgroud)

案例2

如果要在环境变量中未定义值时设置默认值,则第二个解决方案实际上很有用,但不是在您编写的表单中:

server = os.getenv('MY_CAT_STREAMS', 'youtube.com')
Run Code Online (Sandbox Code Playgroud)

也许

server = os.environ.get('MY_CAT_STREAMS', 'youtube.com')
Run Code Online (Sandbox Code Playgroud)

请注意,如果您的应用程序有多个选项,您可能需要查看ChainMap,这允许基于键合并多个dicts.ChainMap文档中有一个例子:

[...]
combined = ChainMap(command_line_args, os.environ, defaults)
Run Code Online (Sandbox Code Playgroud)


Lev*_*von 9

为了安全起见

os.getenv('FOO') or 'bar'
Run Code Online (Sandbox Code Playgroud)

上述答案的一个极端情况是设置了环境变量但为空

对于这种特殊情况,您会得到

print(os.getenv('FOO', 'bar'))
# prints new line - though you expected `bar`
Run Code Online (Sandbox Code Playgroud)

要么

if "FOO" in os.environ:
    print("FOO is here")
# prints FOO is here - however its not
Run Code Online (Sandbox Code Playgroud)

为了避免这种情况,只需使用 or

os.getenv('FOO') or 'bar'
Run Code Online (Sandbox Code Playgroud)

然后你得到

print(os.getenv('FOO') or 'bar')
# bar
Run Code Online (Sandbox Code Playgroud)

什么时候有空的环境变量?

您忘记在.env文件中设置值

# .env
FOO=
Run Code Online (Sandbox Code Playgroud)

或导出为

$ export FOO=
Run Code Online (Sandbox Code Playgroud)

或忘记设置它 settings.py

# settings.py
os.environ['FOO'] = ''
Run Code Online (Sandbox Code Playgroud)

更新:如有疑问,请查看这些单线

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

$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"
Run Code Online (Sandbox Code Playgroud)


小智 9

我推荐以下解决方案。

它会打印您未包含的环境变量,这使您可以一次性添加它们。如果您使用 for 循环,则必须重新运行程序才能查看每个丢失的变量。

from os import environ

REQUIRED_ENV_VARS = {"A", "B", "C", "D"}
diff = REQUIRED_ENV_VARS.difference(environ)
if len(diff) > 0:
    raise EnvironmentError(f'Failed because {diff} are not set')
Run Code Online (Sandbox Code Playgroud)

  • 您不需要检查差异的长度,只需使用“if diff:”即可(也许将“diff”更改为“missing_variables”以获得更具描述性的名称)。同样在 python 3.8 及更高版本中,您可以使用 walrus 运算符对其进行更多压缩:`ifmissing_variables := REQUIRED_ENV_VARS.difference(environ):`。 (3认同)

vha*_*mon 8

如果要检查是否未设置多个 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))
Run Code Online (Sandbox Code Playgroud)