1.django 和 flask的区别?
他们两个相同点都是基于wsig
最大的不同点 是 对于django而言,请求相关的数据 是通过封装到request里面,通过把request传递过去,取响应的数据的。
而 对于 flask 来说,请求相关的数据 是通过上下文管理完成的;
2.什么是wsgi?
web服务网关接口, 就是一个协议(规范),实现该协议的模块:
- wsgiref
- werkzeug
实现其协议的模块本质上就是socket服务端 , 用于接收用户请求,并处理。
一般web框架基于wsgi实现,这样 实现关注点分离(web框架更关注于 接收到请求之后再做逻辑的处理 ;而wsgi则关注于获取socket的请求)
Flask源码的入口:
from werkzeug.serving import run_simple
from werkzeug.wrappers import Response
# run_simple(host, port, self, **options) 自动的给第3个参数加(),用来调用。
# app.__call__
class Flask():
def __call__(self, environ, start_response):
response = Response("hello")
return response(environ, start_response)
def run(self,host="127.0.0.1",port=8000):
run_simple(host, port, self)
app = Flask()
if __name__ == "__main__":
app.run()
这里重点分析app.run() 都干了什么?
首先,执行app.run() 时,源码中显示执行了执行run_simple() 方法,源码中run_simple() 方法的参数是run_simple(host, port, self, **options) ,这里重点看第三个参数self,因为app是flask的实例化对象,因此self就是指flask的实例化对象app,而上例中我们知道当有请求进来的时候,执行了app(),我们知道函数加括号是执行,而对象加括号会自动执行__call__方法,也就是说app.run() 其实是监听了flask类中的__call__方法,
def add:
return ".."
run_simple(host, port, add, **options) , 请求一旦执行将会自动的执行这个add函数,证明 给第三个参数加了括号;如果第三个参数 是对象的话,就会执行 类中的__call__方法。
3. Flask 提供功能:
-配置文件
-所有的配置文件都是在app.config中
- 直接可以配置 app.config["xx"] = 123
- 还可以写一个配置类, 通过app.config.from_object("类的路径") ;配置类也可继承,可得到不同环境下的配置。
- 通过 importlib 以及 getattr 通过 "类的路径"字符串 得到 类,然后dir(cls),isupper,得到这个类中大写的配置属性
应用 : importlib 和 getattr
- django中间件
- rest framework 的全局配置。
-session
- 加密后放置在用户浏览器的cookie中
- 流程:
- 请求到来
- 视图函数
- 请求结束
- 配置文件
默认的session有效时间为31day;
-闪现
- 基于session.pop 实现的,实现了 只能取一次的效果
-路由
- 装饰器(带参数的装饰器)
- 自定义的装饰器放在下面
- 3个参数 :@app.route('/delete/<int:s_id>', methods=["GET", "POST"],endpoint="") ;
endpoint 反向生成url; url_for
-视图
-FBV
-特殊的装饰器
-中间件
- __call__
-模板
-请求和响应
-请求request
-响应:
-4种响应
1.路由 + 视图
'''
带参数的装饰器的原理
def route(self, rule, **options):
def decorator(f):
endpoint = options.pop("endpoint", None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator
'''
'''
@app.route('/index', methods=["GET", "POST"])
执行的过程:
1.先执行
decorator = app.route('/index', methods=["GET", "POST"])
2.
@decorator
def index():
pass
decorator(index)
'''
2. session 实现原理(源码):
session的流程图

3. 蓝图:
目标: 给开发者提供目录结构
其他:
- 自定义的模板,静态文件
- 给某一类的Url添加前缀
app.register_blueprint(ac,url_prefix='/api')
- 给某一类的url添加before_request
@ac.before_request
def xxx():
print("ac.before_request")
@ac.route('/login')
def login():
return render_template("login.html")
4. threading.local
给每个线程开辟自己的一个空间,进行数据隔离。
#把他封装为一个类,这样 跟 threading.local 一样的使用.
# __getattr__ (是在 obj.xxx 的取值的时候调用的 ); __setattr__(obj.xxx = 123 设置值的时候调用的)
#threading.local 的加强版 (不仅包含线程 也包含协程 )
import greenlet
try:
get_ident = threading.get_ident
except Exception:
get_ident = greenlet.getcurrent
class Local(object):
DICT = {}
def __getattr__(self, item):
ident_value = get_ident()
if ident_value in self.DICT:
return self.DICT[ident_value][item]
return None
def __setattr__(self, key, value):
ident_value = threading.get_ident()
if ident_value in self.DICT:
self.DICT[ident_value][key] = value
else:
self.DICT[ident_value] = {key:value}
obj = Local()
def func(i):
global v
v = i
obj.xxx = v
time.sleep(0.5)
print(obj.xxx)
print(threading.get_ident(), i)
for i in range(10):
t = threading.Thread(target=func,args=(i,))
t.start()
5.上下文管理
https://www.cnblogs.com/zenghui-python/articles/11693202.html
flask中的上下文管理机制分为请求上下文和应用上下文两大方面,通过上下文的管理机制,实现了即去即用的一个特色。
flask的上下文管理是基于local来实现的数据存储。数据隔离。
浙公网安备 33010602011771号