在Python中评估布尔环境变量

问题描述 投票:0回答:14

在Python中如何评估环境变量是否为布尔值True?使用是否正确:

if os.environ['ENV_VAR'] is True:
      .......
python-3.x if-statement boolean
14个回答
167
投票

选项1

我觉得这个效果很好:

my_env = os.getenv("ENV_VAR", 'False').lower() in ('true', '1', 't')

它允许:诸如

true
True
TRUE
1
"1"
TrUe
t
T
、...

更新:在阅读了Klaas的评论后,我将原来的代码

my_env = bool(os.getenv(...
更新为
my_env = os.getenv(...
,因为
in
会产生
bool
类型


选项2

更新: 在 @MattG 评论之后,我添加了一个新的解决方案,该解决方案会针对

ttrue
等条目引发错误,而不是返回
False
:

# ...
import os
# ...

def get_variable(name: str, default_value: bool | None = None) -> bool:
    true_ = ('true', '1', 't')  # Add more entries if you want, like: `y`, `yes`, `on`, ...
    false_ = ('false', '0', 'f')  # Add more entries if you want, like: `n`, `no`, `off`, ...
    value: str | None = os.getenv(name, None)
    if value is None:
        if default_value is None:
            raise ValueError(f'Variable `{name}` not set!')
        else:
            value = str(default_value)
    if value.lower() not in true_ + false_:
        raise ValueError(f'Invalid value `{value}` for variable `{name}`')
    return value in true_

# ...

my_env1 = get_variable("ENV_VAR1")
my_env2 = get_variable(name="ENV_VAR2") # Raise error if variable was not set
my_env3 = get_variable(name="ENV_VAR3", default_value=False) # return False if variable was not set

75
投票

都一样,但这对我来说是最易读的版本:

DEBUG = (os.getenv('DEBUG', 'False') == 'True')

这里除了

True
之外的任何内容都将评估为 False。 DEBUG 为 False,除非在 ENV
 中明确设置为 
True


34
投票

我推荐使用

strtobool
功能

示例:

DEBUG = strtobool(os.getenv("DEBUG", "false"))

你可以在Python文档中查看它们 https://docs.python.org/3/distutils/apiref.html#distutils.util.strtobool

只有一个问题,如果您传递错误的值,它们会引发错误

代码

from distutils.util import strtobool

print("Value: ", strtobool("false"))

print("Value: ", strtobool("Wrong value"))

输出

Value:  0
Traceback (most recent call last):
  File "<string>", line 9, in <module>
  File "/usr/lib/python3.8/distutils/util.py", line 319, in strtobool
    raise ValueError("invalid truth value %r" % (val,))
ValueError: invalid truth value 'wrong value'

15
投票

强烈推荐

environs
:

from environs import Env

env = Env()

MY_BOOL_VALUE = env.bool("MY_BOOL_VALUE", False)

if MY_BOOL_VALUE:
    print("MY_BOOL_VALUE was set to True.")
else:
    print("MY_BOOL_VALUE was either set to False or was not defined.")

8
投票

你的这两种方法都行不通。如果键不存在,

os.environ['ENV_VAR']
单独会导致
KeyError
,如果存在,则返回与
'ENV_VAR'
关联的值。在任何一种情况下,您都会出错,或者与
True
"true"
进行比较,这将始终导致
False
(除非与环境变量关联的值恰好是
"true"
;但事实并非如此)你在追寻)。

要检查映射是否包含特定键,您可以使用

in
:

if 'ENV_VAR' in os.environ:
    # It contains the key
else:
    # It doesn't contain the key

6
投票

我使用以下内容来进行更严格的输入并支持输入中更广泛的布尔变化

import os

def getenv_bool(name: str, default: bool = False) -> bool:
    return os.getenv(name, str(default)).lower() in ("yes", "y", "true", "1", "t")

用途:

feature_1=getenv_bool('FEATURE_1', False)

5
投票

另一种接受“false”、“False”、“true”或“True”的选择:

import os
import ast

def getenv_bool(name: str, default: str = "False"):
    raw = os.getenv(name, default).title()
    return ast.literal_eval(raw)

4
投票

如果您不想使用上面提到的环境库,那么 strtobool 非常适合。唯一的问题是它已经被弃用了,似乎没有任何替代库,但幸运的是它只是几行简单的代码,没有依赖关系。只需执行代码即可:

# Copied from distutils.util.strtobool, which is deprecated
def strtobool (val):
    """Convert a string representation of truth to true (1) or false (0).

    True values are case insensitive 'y', 'yes', 't', 'true', 'on', and '1'.
    false values are case insensitive 'n', 'no', 'f', 'false', 'off', and '0'.
    Raises ValueError if 'val' is anything else.
    """
    val = val.lower()
    if val in ('y', 'yes', 't', 'true', 'on', '1'):
        return 1
    elif val in ('n', 'no', 'f', 'false', 'off', '0'):
        return 0
    else:
        raise ValueError("invalid truth value %r" % (val,))

像这样使用它:

my_env_var_value = strtobool(os.getenv("ENV_VAR", "False"))

并且,如果环境变量的值既不是 true 也不是 false,这将引发错误。在大多数情况下,这可能是最好的做法。


2
投票

另一种可能的解决方案是将值解析为 JSON 值:

import json
import os

def getenv(name, default="null"):
    try:
        return json.loads(os.getenv(name, default))
    except json.JSONDecodeError:
        return name

try
适用于无法直接转换的情况。

assert getenv("0") == 0
assert getenv("1.1") = 1.1
assert getenv("true") == True
assert getenv("Hello") = "Hello"
assert getenv('["list", "of", "strings"]') == ["list", "of", "strings"]

1
投票

Python版本: 3.9.13(主要,2022年5月27日,17:01:00)

我使用了下面的解决方案,效果完美;

在你的环境文件中;

SOMEHING_ENABLED=True

以及 python 文件中的用例;

from distutils.util import strtobool

if bool(strtobool(os.getenv('SOMEHING_ENABLED'))):
   # good to go.

不:distutils 从 3.12 版本起将不再工作


1
投票

在 Django 中,如果您使用 python-dotenv,还要确保不要在 .env 文件中使用 DEBUG,因为当我们使用

True
时,它始终默认为
os.getenv("DEBUG")
。使用另一个变量,例如 DEBUG_MODE。例如:

#.env 

DEBUG_MODE = False

#settings.py 

import os
from dotenv import load_dotenv

load_dotenv()
DEBUG = os.getenv("DEBUG_MODE", False) == "True"

0
投票

我更喜欢要求严格将环境变量设置为

True
False
,并且不允许有太多其他模糊的可能性。 另外,如果未定义变量,我想要引发异常。

assert(os.environ['MY_KEY'] in ('True', 'False'))

if os.environ['MY_KEY'] == 'True':
    # True
    pass
else:
    # False
    pass

如果未定义

KeyError
,则会引发
MY_KEY
;如果未设置为“True”或“False”,则会引发
AssertionError

如果您经常这样做并因此想要一个功能,请使用这个:

def get_env_bool(key):
    """ Handles the case of a boolean environment variable
    """
    if not key in os.environ:
        raise KeyError(f"No environment variable {key}")

    if not os.environ[key] in ('True', 'False'):
        raise AssertionError(f"Key {key} is not proper boolean: {os.environ[key]}")

    return os.environ[key] == 'True'

用途:

if get_env_bool('MY_KEY'):
   ...

0
投票

这是我的 2 美分:为什么不使用 YAML?

代码:

import os, yaml

bool(yaml.load(os.getenv(MY_VAR) or "", yaml.Loader))

测试:

for val, expected in {
    "yes": True,
    "no": False,
    "on": True,
    "off": False,
    "true": True,
    "false": False,
    "1": True,
    "0": False,
    "": False,
    None: False,
}.items():
    actual = bool(yaml.load(val or "", yaml.Loader))
    assert actual == expected

-4
投票

我的看法 - 为什么不使用内置的

bool()
,它类似于
str()

import os

my_boolean_env_var = bool(os.getenv("MY_ENV_VAR"))
© www.soinside.com 2019 - 2024. All rights reserved.