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来实现的数据存储。数据隔离。

posted on 2019-10-19 16:11  小辉python  阅读(174)  评论(0编辑  收藏  举报