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

evrscar2  于 2023-09-29  发布在  Python
关注(0)|答案(6)|浏览(155)

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

if "FOO" in os.environ:
    pass

方法二:

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

我想知道哪种方法,如果有的话,是一个好的/首选的条件和为什么。

jm81lzqq

jm81lzqq1#

使用第一个;它直接尝试检查environ中是否定义了某些内容。虽然第二种形式同样工作得很好,但它缺乏语义,因为如果它存在,您将返回一个值,并且 * 仅 * 将其用于比较。
你想看看environ中是否有东西存在,为什么你只是比较它然后把它扔掉呢?
这正是getenv所做的:

  • 获取一个环境变量 *,如果不存在则返回None。可选的第二个参数可以指定替代默认值。

(this也意味着您的检查可能只是if getenv("FOO")
你不想得到它,你想检查它的存在。
无论哪种方式,getenv都只是environ.get的 Package 器,但您不会看到人们使用以下命令检查Map中的成员关系:

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

要进行总结,请用途:

if "FOO" in os.environ:
    pass

如果你只是想检查是否存在,而如果你真的想对你可能得到的值做些什么,请使用getenv("FOO")

lvjbypge

lvjbypge2#

这两种解决方案都有各自的情况,具体取决于您希望在环境变量存在的条件下执行的操作。

案例一

当你想纯粹根据环境变量的存在而采取不同的操作,而不关心它的值时,第一个解决方案是最佳实践。它简洁地描述了您测试的内容:是环境变量列表中的'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,它允许基于键合并多个dicts。在ChainMap文档中有一个这样的例子:

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

正如@Levon所指出的,如果变量被设置为空,这可能会返回意外的结果。因此,您还应该检查返回的值。例如:

combined = ChainMap(command_line_args, os.environ)
server = combined.get("MY_CAT_STREAMS") or defaults["MY_CAT_STREAMS"]
iibxawm4

iibxawm43#

为了安全起见,使用

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'))"
li9yvcax

li9yvcax4#

如果你想检查多个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))
eoxn13cs

eoxn13cs5#

我推荐以下解决方案。
它会打印出你没有包括的环境变量,这样你就可以一次添加它们。如果你使用for循环,你将不得不重新运行程序来查看每个丢失的var。

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

gpnt7bae6#

考虑到你正在使用一个名为Foo的环境变量,它可能会根据不同的环境而改变,我建议你获取它的值,即使你使用它的值(例如:boolean)作为切换或决策标准。它可以帮助你当出了问题或只是为健全检查后。

#python=3.8

import os
import logging

foo = os.getenv("FOO")

if foo:
    logging.info(f"Proceeding since environment variable FOO exists {foo=}")
    pass
else:
    # proper action/logging based on the context
    pass

我建议不要在没有适当日志记录的情况下在代码本身中硬编码替代方案。使用foo = os.getenv("FOO", "BAR")可能会悄悄地更改代码的行为。
此外,最好将所有常量放在配置文件中或作为环境变量,不要在源代码中硬编码任何内容。默认值和备选项可以放在配置文件中,环境更改常量应该是env变量,以便您可以在部署期间轻松更改它们。

相关问题