在根目录下建立一个app/web文件夹,在这个文件夹下面建立一个book.py文件,专门用来存放book模块,然后在主文件中引用这个模块就可以了,book.py
# -*- coding: utf-8 -*- from flask import jsonify from helper import is_isbn_key from ShanqiuBook import ShanqiuBook # 为了让book.py模块可以使用app对象 from demo import app @app.route('/book/search/<q>/<page>') def hello(q,page): # 调用方法判断用户是根据什么查的 is_or_key = is_isbn_key(q) if is_or_key == 'isbn': result = ShanqiuBook.search_by_isbn(q) else: result = ShanqiuBook.search_by_keyword(q) return jsonify(result)此时的主文件中
# -*- coding: utf-8 -*- from flask import Flask # 为了可以注册book.py中的路由 from app.web import book app = Flask(__name__) app.config.from_object('config') if __name__ == '__main__': app.run(debug=app.config['DEBUG'])但是这样写的话,会出现404,因为出现了循环引用
循环引入流程分析因为在整个的流程中,app两次初始化,如图
整个流程中,出现了两次核心app对象的初始化,注册路由是在蓝色流程中初始化的app注册的。但是启动服务是红色流程中的app启动的
book中注册路由所使用的app对象,是他自己所导入fisher模块的app对象(蓝色流程中),而不是红色主流程中所实例化的app对象
问题1:因为都是由fisher引入book,一个模块只会引入另一个模块一次,所以只执行了一次book
问题2:由于一次是主流程执行fisher文件;一次是由book模块导入 fisher
为了验证我们的结论,我们在app实例化,启动,注册路由是哪个地方加入日志信息,
print("id为"+str(id(app))+"的app注册路由") @app.route("/book/search/<q>/<page>") def search(q, page): isbn_or_key = is_isbn_or_key(q) if isbn_or_key == 'isbn': result = YuShuBook.search_by_isbn(q) else: result = YuShuBook.search_by_key(q) return jsonify(result)主文件
app = Flask(__name__) print("id为"+str(id(app))+"的app实例化") app.config.from_object("config") # 为了可以注册book.py中的路由 from app.web import book if __name__ == '__main__': print("id为" + str(id(app)) + "的app启动") app.run(debug=app.config['DEBUG'])结果如下
id为92323280的app实例化 id为107142192的app实例化 id为107142192的app注册路由 id为92323280的app启动可以看到注册路由的app,和启动服务的app不是同一个app。并且最后启动的app是最先实例化的app,也就是红色主流程的app;而注册路由的app是后实例化的app,也就是由book导入fisher模块的蓝色流程的app