最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】Flask中从.env中加载ini类型的配置得到的变量类型不是原始类型而都是字符串

字符串 crifan 1436浏览 0评论
折腾:
【未解决】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
python – os.getenv returns None instead correct value – Stack Overflow
python – Difference between os.getenv and os.environ.get? – Stack Overflow
python – Setting/reading environment variables – Stack Overflow
看来只能去手动强制转换变量的原始类型了
os.getenv Python Example
16.1. os — Miscellaneous operating system interfaces — Python 3.7.0 documentation
“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

转载请注明:在路上 » 【已解决】Flask中从.env中加载ini类型的配置得到的变量类型不是原始类型而都是字符串

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
80 queries in 0.174 seconds, using 22.15MB memory