在问了之前的问题后,有人告诉我我的应用程序的组织很奇怪,所以我查看了其他示例,看看如何处理我想做的事情。
我发现的最清晰的例子是学校的Flask应用案例。据我了解:
app
对象在app模块中声明路由在routes模块中声明
蓝图导入我想要的路线
但是,在我的应用程序中,为了回答一些路由,我需要访问 app 模块中定义的参数(它们在创建应用程序对象之前使用)。
如何在 routes 模块中访问这些参数?
我不能只从 app 导入它们,因为这将是循环导入。
我可以使用这个问题中建议的构造函数,但考虑到我上一个问题的注释,这似乎不是处理这个问题的常用方法。
听起来您可能需要使用基于类的视图。
您面临的问题是,您在视图函数运行时需要值,但很难将它们导入到定义函数的路由模块中。您最初尝试使用函数中的函数来解决这个问题(虽然完全有效,但不太符合 Python 风格)。
我建议创建一个
views.py
文件并定义一个基于类的视图(或者你可以称之为 routes.py
,这并不重要):
from flask.views import View
class MyView(View):
methods = ['GET']
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
def dispatch_request(self):
return 'param1: {}\nparam2: {}'.format(self.param1, self.param2)
def add_routes(app, param1, param2):
# `param1` and `param2` will get passed to the view class constructor
app.add_url_rule('/', view_func=MyView.as_view('myview', param1, param2))
然后,在您的
server.py
文件(或任何您所称的名称)中,您可以将应用程序和参数传递给 add_routes
函数:
from flask import Flask
from .views import add_routes
param1 = 'foo'
param2 = 'bar'
app = Flask(__name__)
add_routes(app, param1, param2)
add_routes
不必住在views.py
,它可以住在任何地方。或者,如果您没有很多路线,您可以完全摆脱它:
from flask import Flask
from .views import MyView
param1 = 'foo'
param2 = 'bar'
app = Flask(__name__)
app.add_url_rule('/', view_func=MyView.as_view('myview', param1, param2))
请注意,该类将在每个请求时实例化,而不仅仅是一次。因此,您不应该在构造函数中执行任何特别密集的操作(例如读取文件)。
遵循史蒂夫的回答精神,我得到了这个可行的解决方案:
在
routes.py
:
class Routes:
# constructor
def __init__(self, config: dict):
self.__config = config
# init_session
def init_session(self, type_response: str):
# using the config
config = self.__config
...
# authenticate_user
def authenticate_user(self):
# using the config
config = self.__config
...
在
main.py
config={...}
# Flask app
app = Flask(__name__, template_folder="../templates", static_folder="../static")
# routes # routes
from routes import Routes
# class instance with needed parameters
routes = Routes(config)
# adjusting urls with routes
app.add_url_rule('/init-session/<string:type_response>', methods=['GET'],
view_func=routes.init_session)
app.add_url_rule('/authenticate-user', methods=['POST'],
view_func=routes.authenticate_user)