在Flask中处理应用程序配置时,通常建议使用config
对象上可用的flask.Flask
字典,例如flask.current_app.config["TESTING"]
。
对此进行填充的一个建议是使用类和继承为每个环境分隔配置:
class Config:
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite:///:memory:'
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config):
DEBUG = True
# Example usage:
app = flask.Flask(__name__)
app.config.from_object(ProductionConfig)
db_uri = app.config["DATABASE_URI"]
这样做的缺点是,尽管已经使用类属性定义了键,但是我们还是使用字符串键来访问它们,而这些键最终会在代码周围被引用。如果我键入错误的键,则不会在我的IDE中收到警告,并且会在运行时得到KeyError
。我也没有得到配置中对象的类型推断。
能够以类似方式填充Flask配置很好,但是可以更好地访问这些值,就像我可以访问对象上的普通属性一样。
我已经想到了一些方法,但是似乎都没有一个理想的方法:
get_database_uri()
-只要这是访问配置的唯一方法,就知道可用的键及其值的类型。需要为每个新的配置键编写一个函数。Config
对象,例如app.config["config"] = ProductionConfig()
。使用类型提示或包装函数,我们可以输入内容,但是将配置对象存储在配置中很奇怪,并且我们无法自动设置Flack特定值,例如TESTING
。app.config
,并使用其他任何解决方案。有没有人发现还可以与Flask的配置集成的更清洁的解决方案?
答案 0 :(得分:3)
可以通过覆盖app.config
来配置用于Flask.config_class
的类。编写flask.config.Config
的子类,该子类定义__getattr__
来查找密钥,并将其分配给config_class
属性。
from flask.app import Flask
from flask.config import Config
class AttrConfig(Config):
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(key)
def __dir__(self):
out = set(self.keys())
out.update(super().__dir__())
return sorted(out)
class CustomFlask(Flask):
config_class = AttrConfig
app = CustomFlask(__name__)
但是,鉴于它们是动态加载的,因此没有可靠的方法可以使IDE理解这些属性。实现__dir__
将使它们显示在Python或IPython Shell的制表符补全中,但是IDE通常不执行模块代码以提供自省功能,因此这不会影响它们。