折腾:
【未解决】Flask中如何利用环境变量实现自动加载开发还是生产的配置
期间,经过调试:
另外,再去改为之前的代码:
app.config.from_object('config.DevelopmentConfig')
# app.config.from_object('config.ProductionConfig')
print("for debug: after load from config.DevelopmentConfig: app.config=%s" % (app.config))
# app.config.from_object(settings)
# print("for debug: after load from settings: app.config=%s" % (app.config))看看输出结果是不是完全一样 -》 以确保此处的config是和之前的方式的效果是一样的,没有其他不良影响
结果发现了还是有点点影响的:

即:
从settings中导入的值,都是字符串:
之前的:
DEBUG=True
变成了:
‘DEBUG’: ‘True’,
而不是希望的:
‘DEBUG’: True,
发现:
从.env中用
os.getenv
加载的int的配置
都只是字符串,而不是原始的配置的类型的值
比如int,bool等
-》那再去故意弄一些,其他类型,比如数字,看看是否也是字符串
DEMO_INT = 1000 DEMO_COMPLEX_INT = 2 * 10
果然还是字符串:


所以现在问题来了:
希望从settings中加载的变量,都可以转换为特定的类型,比如bool,int等等
感觉像是:
每个变量,手动类型转换?
或者是从ini等配置文件中,加载变量,自动判断类型?
不过突然觉得又好像不现实:
貌似即使从.env的int得到了要的变量的类型,而此处从
os.getenv
得到的变量,好像也只能是字符串吧?
所以去搜搜看
os.getenv get variable type
python os get environment keep type
看来只能去手动强制转换变量的原始类型了
“os.getenv(key, default=None)
Return the value of the environment variable key if it exists, or default if it doesn’t. key, defaultand the result are str.”
官网说了:os.getenv只是返回字符串
所以只能自己手动转换类型了。
所以改为:
# DEBUG = os.getenv("DEBUG")
DEBUG = bool(os.getenv("DEBUG"))
MONGODB_HOST = os.getenv("MONGODB_HOST")
FILE_URL_HOST = os.getenv("FILE_URL_HOST")
# DEMO_INT = os.getenv("DEMO_INT")
# DEMO_COMPLEX_INT = os.getenv("DEMO_COMPLEX_INT")
DEMO_INT = int(os.getenv("DEMO_INT"))
DEMO_COMPLEX_INT = int(os.getenv("DEMO_COMPLEX_INT"))结果

但是复杂的数字的表达式,就不支持了:
DEMO_COMPLEX_INT = int(os.getenv("DEMO_COMPLEX_INT"))
ValueError: invalid literal for int() with base 10: '2 * 10'
所以为了避免歧义,则:
【总结】
.env中:
- 最好全部都改为字符串
- 且都是简单的值
- 不要写数字的表达式,比如 2 * 60 * 60
举例如下:
;DEBUG = True DEBUG = "True" # for local dev, need access remote mongodb MONGODB_HOST = "xxx" FILE_URL_HOST = "127.0.0.1" DEMO_INT = "1000" ;DEMO_COMPLEX_INT = 2 * 10
然后settings中,先os.getenv获取字符串,再调用类型转换,int(),bool()等,去转换为自己需要的值
DEBUG = bool(os.getenv("DEBUG"))
MONGODB_HOST = os.getenv("MONGODB_HOST")
FILE_URL_HOST = os.getenv("FILE_URL_HOST")
DEMO_INT = int(os.getenv("DEMO_INT"))
# DEMO_COMPLEX_INT = int(os.getenv("DEMO_COMPLEX_INT"))
print("After load .env: DEBUG=%s, MONGODB_HOST=%s, FILE_URL_HOST=%s, DEMO_INT=%s" %
(DEBUG, MONGODB_HOST, FILE_URL_HOST, DEMO_INT))算是基本上满足了此处的需求了:
输出对应类型的数据了:


【后记】
发现直接判断False或True的字符串,是不正确的,因为:
bool("False") -> True所以要去改为:
# DEBUG = os.getenv("DEBUG")
# DEBUG = bool(os.getenv("DEBUG"))
debug_str = os.getenv("DEBUG")
if debug_str:
debug_str_lower = debug_str.lower()
if (debug_str_lower == "false") or (debug_str_lower == "0"):
DEBUG = False
elif (debug_str_lower == "true") or (debug_str_lower == "1"):
DEBUG = True