逆水行舟用力撑,一篙松劲退千寻。这篇文章主要讲述如何在app工厂模式中管理额外的模块?相关的知识,希望能为你提供帮助。
我正在使用带有app工厂模式的烧瓶。我知道app工厂模式仅在工厂函数中管理配置对象。 (如下面的代码所示)
def create_app(config):
app.config.from_object(config)
sentry.init(app)
...return app
但是,如何管理需要该配置的额外模块,但无法在应用创建时创建初始化?
所以我想做点什么
def create_app(config):
some_module_obj = Module(host=config.host, port=config.port)app.config.from_object(config)
sentry.init(app)return some_module_obj, app
而不是
# I don't want to use `config` outside of the `create_app` function!
some_module_obj = Module(host=config.host, port=config.port)def create_app(config):
app.config.from_object(config)
sentry.init(app)return app
答案不确定这是你需要的,但你在评论中要求一个小例子与
inject + Flask
。据我所知,主要问题与Flask + configuration + initialization
有关。这只是它如何工作的一个例子。app.朋友:
from flask import Flaskfrom api import bp
from configurator import configuredef create_app():
app = Flask(__name__)
# configure Flask app config as you wish... (app.config.from_object(config))
# just some settings for demonstration
app.config.update(dict(
MODULE1_TIMER=1,
MODULE2_LIMIT=2,
))
# configure inject using app context and Flask config
with app.app_context():
configure()
# demo blueprint
app.register_blueprint(bp)return appif __name__ == '__main__':
create_app().run(debug=True)
让我们假设我们有一些模块:
# mod1.py
class Module1:
def __init__(self, timer: int) ->
None:
self._timer = timer# mod2.py
class Module2:
def __init__(self, limit: int) ->
None:
self._limit = limitdef get_limit(self):
return self._limit# mod3.py - works with mod1 and mod2
class Module3:
def __init__(self, module1, module2) ->
None:
self._module1 = module1
self._module2 = module2def get_limit(self):
return self._module2.get_limit()
config u rat or.朋友:
import inject
from flask import current_appfrom mod1 import Module1
from mod2 import Module2
from mod3 import Module3@inject.params(
module1=Module1,
module2=Module2,
)
def _init_module3(module1, module2):
# module1 and module2 are injected instances
return Module3(module1, module2)def _injector_config(binder):
# initialization of Module1 and Module2 using Flask config
binder.bind(Module1, Module1(current_app.config['MODULE1_TIMER']))
binder.bind(Module2, Module2(current_app.config['MODULE2_LIMIT']))
# initialization of Module3 using injected Module1 + Module2
# you can use bind_to_constructor + any function
binder.bind_to_constructor(Module3, _init_module3)def configure():
def config(binder):
binder.install(_injector_config)
# one more binder.install... etc...inject.clear_and_configure(config)
API.朋友:
import inject
from flask import Blueprint, jsonifyfrom mod1 import Module1
from mod2 import Module2
from mod3 import Module3bp = Blueprint('api', __name__)@bp.route('/test')
def test():
# get instances which was created using inject
return jsonify(dict(
module1=str(type(inject.instance(Module1))),
module2=str(type(inject.instance(Module2))),
module3=str(type(inject.instance(Module3))),
))# you can inject something as arg
@bp.route('/test2')
@inject.params(module3=Module3)
def test2(module3: Module3):
return jsonify(dict(module3=str(type(module3))))@bp.route('/test3')
def test3():
# you can inject something into anything
class Example:
module3 = inject.attr(Module3)@inject.params(module2=Module2)
def __init__(self, module2: Module2) ->
None:
self.module2 = module2return jsonify({
'MODULE2_LIMIT': Example.module3.get_limit(),
'example': dir(Example()),
})
运行服务器,打开qazxsw poi,qazxsw poi,qazxsw poi。
关于好处的几句话:
- 初始化和配置的一点
- 降低对current_app,flask配置/上下文等的依赖性
- 减少递归导入的问题
- 易于编写测试
另一答案决定将初始化对象的自定义类作为工厂模式。
这是一个例子:
/test
【如何在app工厂模式中管理额外的模块()】并在
test2
(具有/test3
功能)class CustomFactory(metaclass=ABCMeta):
@abstractmethod
def init_factory(self, config):
pass@property
@abstractmethod
def app(self):
passdef __getattr__(self, item):
return getattr(self.app, item)class RQSchedulerFactory(CustomFactory):
def __init__(self):
self._app = Nonedef init_factory(self, config):
self._app = Scheduler(connection=Redis(host=config.REDIS_HOST, port=config.REDIS_PORT))@property
def app(self):
return self._appclass FireDBFactory(CustomFactory):
@property
def app(self):
return self._appdef __init__(self):
self._app = Nonedef init_factory(self, config):
cred = credentials.Certificate(config.FIREBASE_KEY_FILE)
firebase_admin.initialize_app(cred)self._app = firestore.client()
在
__init__.py
函数中,初始化如下:create_app
推荐阅读
- 如何在Kali Linux中使用GoLismero搜索网站中的安全漏洞
- 使用app factory flask时,在单独的文件中定义模型
- React Native,Android Studio,JDBC,MySql - 拒绝访问用户'root'@'ipaddress'
- 麻烦.apply()带'int'列的方法
- Android(将片段和弹出窗口的点击事件中生成的变量传递给活动的方法)
- Android Clean Architecture中的登录流程
- 在Android 4.x中显示矢量图形
- android super.onBackPressed()计时
- Android P onStart在onActivityResult之前调用