如何在app工厂模式中管理额外的模块()

逆水行舟用力撑,一篙松劲退千寻。这篇文章主要讲述如何在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


    推荐阅读