Flask(3)- flask中的CBV、werkzeug+上下文初步解读、偏函数和线程安全
一、flask中的CBV
对比django中的CBV,我们来看一下flask中的CBV怎么实现?
from flask import Flask, render_template, url_for, views app = Flask(__name__) class Login(views.MethodView):
def get(self):
print(url_for("my_login")) # /login
return render_template("login.html") def post(self):
return "login success" app.add_url_rule("/login", view_func=Login.as_view("my_login")) if __name__ == '__main__':
app.run(debug=True)
注意:视图类中定义了哪些方法,就可以允许哪种方式的请求,也可以通过指定参数methods=["GET","POST"],指定参数时可以在视图类中指定,也可以在add_url_rule方法中指定。
二、werkzeug + 上下文初步解读
通过查看源码,我们知道app.run() 方法其实是执行了run_simple() 方法,源码如下:

我们可以通过下面一段代码探究run_simple() 方法都做了什么?
from werkzeug.serving import run_simple
from werkzeug.wrappers import Request, Response @Request.application
def app(req):
print(req.method) # GET
print(req.path) # /
return Response('200 ok') run_simple('0.0.0.0', 5000, app)
运行代码,发现服务运行在http://0.0.0.0:5000/上,如下:

浏览器访问该网址控制台显示的网址,输出结果如上图,且页面显示返回结果'200 ok'。由此说明视图函数app执行了,再看我们之前写的代码:
from flask import Flask, ... app = Flask(__name__) ......
app.run(debug=True) # app 是flask的实例化对象
这里重点分析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__方法,通过解读源码我们发现__call__方法内容如下:

__call__方法中执行了wsgi_app方法,源码如下:

request_context() 方法源码如下,其中的self仍然是Flask的实例化对象app:

RequestContext是一个类,它的__init__方法源码如下:

本篇暂时解读到这里,下篇继续解读。
三、偏函数和线程安全
1、偏函数就是把前边的值传进来但是不执行
1)示例一
from functools import partial def ab(a,b):
print(a,b) # 1 5
return a+b par_ab = partial(ab, 1) # par_ab是一个新函数,接受了括号中的参数 print(par_ab)
# functools.partial(<function ab at 0x00000203FAB01E18>, 1) print(par_ab(5))
#
# par_ab(5)会执行新函数,且partial(ab, 1)中参数1会成为新函数par_ab的第一个参数,par_ab(5)中的5会成为第二个参数,新函数的函数体是ab函数
2)示例二
from functools import partial def ab(a,*args):
print(a,args)
return a par_ab = partial(ab, 1, 5, 7, 9) print(par_ab)
# functools.partial(<function ab at 0x0000020396711E18>, 1, 5, 7, 9)
# 新函数不加括号不执行
2、线程安全
1)示例一:
import time class Foo(object):
pass foo = Foo() def add(i):
foo.num = i
time.sleep(1)
print(foo.num) for i in range(20):
add(i)
总结:等待时间长
2)示例二:开启线程
import time
import threading class Foo(object):
pass
foo = Foo() def add(i):
foo.num = i
time.sleep(1)
print(foo.num, i) for i in range(20):
th = threading.Thread(target=add, args=(i,))
th.start()
总结:数据不安全
3)示例三:
import time
import threading
from threading import local class Foo(local):
pass foo = Foo() def add(i):
foo.num = i
time.sleep(1)
print(foo.num, i, threading.current_thread().ident) for i in range(20):
th = threading.Thread(target=add, args=(i,))
th.start()
总结:完美解决问题,采用了以空间换取时间的方法,为每个线程保存了一块空间,使线程之间互相不受影响。
Flask(3)- flask中的CBV、werkzeug+上下文初步解读、偏函数和线程安全的更多相关文章
- Flask中的CBV和上下文初步解读
一 . flask中的CBV 相对于Django中的CBV,让我们来看看flask中的CBV是如何实现的 ? from flask import Flask, render_template, url ...
- Flask系列07--Flask中的CBV, 蓝图的CBV
一.CBV使用 class base view 和django中类似 class Login(views.MethodView): # methods=["POST"," ...
- Flask中的CBV以及正则表达式
Flask中的CBV以及正则表达式 一.CBV def auth(func): def inner(*args, **kwargs): print('before') result = func(*a ...
- Flask中的CBV
Flask中的CBV 第一种 class Index(views.MethodView): methods = ['GET', 'POST'] decorators = [] def get(self ...
- flask中的CBV和FBV
flask中CBV使用 from flask import Flask, views app = Flask(__name__) class Login(views.MethodView): meth ...
- Flask 中的 CBV 与上传文件
from flask import Flask, views, render_template, request app = Flask(__name__) app.config['DEBUG'] = ...
- 【Flask】Flask上下文
# 上下文: ### Local对象:在`Flask`中,类似于`request`的对象,其实是绑定到了一个`werkzeug.local.Local`对象上.这样,即使是同一个对象,那么在多个线程中 ...
- flask --- 03 .特殊装饰器, CBV , redis ,三方组件
一.特殊装饰器(中间件) 1.before_request 在请求进入视图函数之前 @app.before_request def look(): 2. after_request 在结束视图函数之后 ...
- 02 flask 请求钩子、异常捕获、上下文、Flask-Script 扩展、jinja2 模板引擎、csrf防范
一 请求勾子 在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如: 在请求开始时,建立数据库连接: 在请求开始时,根据需求进行权限校验: 在请求结束时,指定数据的交互格式: 为了让每个 ...
随机推荐
- 150. Best Time to Buy and Sell Stock II【medium】
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- datatables 相关文章
http://blog.csdn.net/zhu_xiao_yuan/article/details/51252300 datatables参数配置详解 http://blog.csdn.net/j ...
- 浅谈配置文件:spring-servlet.xml(spring-mvc.xml) 与 applicationContext.xml
在搭建 spring mvc 的框架时,会有2个配置文件必不可少: spring-servlet.xml 和applicationContext.xml.第一次接触spring mvc的工程师可能会对 ...
- requireJS的匿名模块和命名模块的区别和最佳实践
requirejs是一个简单的javascript框架,支持模块化编码和模块的异步载入. 在requireJS中模块能够分为:匿名模块和命名模块这2种. requireJS定义一个匿名模块 defin ...
- shell常用的判断条件
.判断文件夹是否存在 if [ -d /home/q/www ];then echo "true"; else echo "false" ;fi (系统内存在文 ...
- ES查看配置和查看全部配置
http://10.0.0.17:9200/blog/_settings GET 获取单个index(库的配置) http://10.0.0.17:9200/_settings/_all GE ...
- 【Java】之static静态方法与非static静态方法区别
1.A.class:没有static public class A { public String getText(){ } B.class调用A的方法时 public class B { publi ...
- datagrid多复选框
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>Ch ...
- Swift-9-类和结构体
// Playground - noun: a place where people can play import UIKit // 几个重要的概念Properties/Methods/Subscr ...
- 第一百四十三节,JavaScript,利用封装库做百度分享
JavaScript,利用封装库做百度分享 效果图 html代码 <div id="share"> <h2>分享到</h2> <ul> ...