在Python中如何评估环境变量是否为布尔值True?使用是否正确:
if os.environ['ENV_VAR'] is True:
.......
我觉得这个效果很好:
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
类型
更新: 在 @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
都一样,但这对我来说是最易读的版本:
DEBUG = (os.getenv('DEBUG', 'False') == 'True')
这里除了
True
之外的任何内容都将评估为 False。 DEBUG 为 False,除非在 ENV中明确设置为
True
我推荐使用
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'
强烈推荐
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.")
你的这两种方法都行不通。如果键不存在,
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
我使用以下内容来进行更严格的输入并支持输入中更广泛的布尔变化
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)
另一种接受“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)
如果您不想使用上面提到的环境库,那么 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,这将引发错误。在大多数情况下,这可能是最好的做法。
另一种可能的解决方案是将值解析为 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"]
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 版本起将不再工作
在 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"
我更喜欢要求严格将环境变量设置为
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'):
...
这是我的 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
我的看法 - 为什么不使用内置的
bool()
,它类似于 str()
import os
my_boolean_env_var = bool(os.getenv("MY_ENV_VAR"))