中间件、猴子补丁、蓝图、请求上下文执行流程

## 1 中间件(跟django中间件完全不一样)

```python
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
# 模拟中间件
class Md(object):
def __init__(self,old_wsgi_app):
self.old_wsgi_app = old_wsgi_app

def __call__(self, environ, start_response):
print('开始之前')
ret = self.old_wsgi_app(environ, start_response)
print('结束之后')
return ret

if __name__ == '__main__':
#1我们发现当执行app.run方法的时候,最终执行run_simple,最后执行app(),也就是在执行app.__call__方法
#2 在__call__里面,执行的是self.wsgi_app().那我们希望在执行他本身的wsgi之前做点事情。
#3 所以我们先用Md类中__init__,保存之前的wsgi,然后我们用将app.wsgi转化成Md的对象。
#4 那执行新的的app.wsgi_app,就是执行Md的__call__方法。
#把原来的wsgi_app替换为自定义的,

app.wsgi_app = Md(app.wsgi_app)
app.run()
```

## 2 猴子补丁

```python
# 什么是猴子补丁?
# 只是一个概念,不属于任何包和模块
# 利用了python一切皆对象的理念,在程序运行过程中,动态修改方法
# 概念
# class Monkey():
# def play(self):
# print('猴子在玩')
#
#
# class Dog():
# def play(self):
# print('狗子在玩')
#
# m=Monkey()
# # m.play()
# m.play=Dog().play
#
# m.play()

# 有什么用?
# 这里有一个比较实用的例子,
# 很多用到import json,
# 后来发现ujson性能更高,
# 如果觉得把每个文件的import json改成import ujson as json成本较高,
# 或者说想测试一下ujson替换是否符合预期, 只需要在入口加上:

# 只需要在程序入口

# import json
# import ujson
#
# def monkey_patch_json():
# json.__name__ = 'ujson'
# json.dumps = ujson.dumps
# json.loads = ujson.loads
# monkey_patch_json()
#
# aa=json.dumps({'name':'lqz','age':19})
# print(aa)



#协程:单线程下实现并发
# from gevent import monkey;monkey.patch_all()
# import gevent
# import time
# def eat():
# print('eat food 1')
# time.sleep(2)
# print('eat food 2')
#
# def play():
# print('play 1')
# time.sleep(1)
# print('play 2')
#
# g1=gevent.spawn(eat)
# g2=gevent.spawn(play)
# gevent.joinall([g1,g2])
# print('主')
```

## 3 蓝图(blueprint)

```python
1 没有蓝图之前前,都是单文件
2 有了蓝图可以分文件,分app,之前的请求扩展还是一样用,只是在当前蓝图对象管理下的有效
3 蓝图使用
#第一步在app中注册蓝图,括号里是一个蓝图对象
app.register_blueprint(user.us)
# 第二步,在不同文件中注册路由时,直接使用蓝图对象注册,不用使用app了,避免了循环导入的问题
@account.route('/login.html', methods=['GET', "POST"])
4 中小型项目目录划分
项目名字
-pro_flask文件夹
-__init__.py
-templates
-login.html
-statics
-code.png
-views
-blog.py
-account.py
-user.py
-run.py

5 大型项目
项目名
-pro_flask文件夹
-__init__.py
-web
-__init__.py
-static
-views.py
-templates
-admin
-templates
-static
-views.py
-__init__.py
-run.py

```

## 4 threading.local

```python
###############1 不用local,多线程写同一个数据,会导致错乱
# from threading import Thread
# import time
# lqz = -1
# def task(arg):
# global lqz
# lqz = arg
# time.sleep(2)
# print(lqz)
#
# for i in range(10):
# t = Thread(target=task,args=(i,))
# t.start()


################2 使用local对象,多线程写同一数据不会错乱,因为每个线程操作自己的数据
# from threading import Thread
# from threading import local
# import time
# from threading import get_ident
# # 特殊的对象
# lqz = local()
# # {'线程id':{value:1},'线程id':{value:2}....}
# def task(arg):
# lqz.value = arg
# time.sleep(2)
# print(lqz.value)
# for i in range(10):
# t = Thread(target=task,args=(i,))
# t.start()


#######3自己写一个类似local的东西,函数版本
# from threading import get_ident,Thread
# import time
# storage = {}
# #{'线程id':{value:1},'线程id':{value:2}....}
# def set(k,v):
# ident = get_ident()
# if ident in storage:
# storage[ident][k] = v
# else:
# storage[ident] = {k:v}
# def get(k):
# ident = get_ident()
# return storage[ident][k]
# def task(arg):
# set('val',arg)
# v = get('val')
# print(v)
#
# for i in range(10):
# t = Thread(target=task,args=(i,))
# t.start()



#######4自己写一个类似local的东西,面向对象版本
# from threading import get_ident,Thread
# import time
# class Local(object):
# storage = {}
# def set(self, k, v):
# ident = get_ident()
# if ident in Local.storage:
# Local.storage[ident][k] = v
# else:
# Local.storage[ident] = {k: v}
# def get(self, k):
# ident = get_ident()
# return Local.storage[ident][k]
# obj = Local()
# def task(arg):
# obj.set('val',arg)
# time.sleep(1)
# v = obj.get('val')
#
# print(v)
# for i in range(10):
# t = Thread(target=task,args=(i,))
# t.start()

# #######3自己写一个类似local的东西,面向对象支持 . 取值赋值
# from threading import get_ident,Thread
# import time
# class Local(object):
# storage = {}
# def __setattr__(self, k, v):
# ident = get_ident()
# if ident in Local.storage:
# Local.storage[ident][k] = v
# else:
# Local.storage[ident] = {k: v}
# def __getattr__(self, k):
# ident = get_ident()
# return Local.storage[ident][k]
# obj = Local()
#
# def task(arg):
# obj.val = arg
# time.sleep(1)
# print(obj.val)
# for i in range(10):
# t = Thread(target=task,args=(i,))
# t.start()


#######4 每次实例化得到一个local对象,用自己的字典存储
# from threading import get_ident,Thread
# import time
# class Local(object):
# def __init__(self):
# object.__setattr__(self,'storage',{})
# # self.storage={} # 这种方式不能用
# def __setattr__(self, k, v):
# ident = get_ident()
# if ident in self.storage:
# self.storage[ident][k] = v
# else:
# self.storage[ident] = {k: v}
# def __getattr__(self, k):
# ident = get_ident()
# return self.storage[ident][k]
# obj = Local()
# def task(arg):
# obj.val = arg
# time.sleep(1)
# print(obj.val)
# for i in range(10):
# t = Thread(target=task,args=(i,))
# t.start()

######5支持线程和协程
# try:
# from greenlet import getcurrent as get_ident
# except Exception as e:
# from threading import get_ident
# from threading import Thread
# import time
# class Local(object):
# def __init__(self):
# object.__setattr__(self,'storage',{})
# def __setattr__(self, k, v):
# ident = get_ident()
# if ident in self.storage:
# # self.storage[ident][k] = v
# # else:
# # self.storage[ident] = {k: v}
# def __getattr__(self, k):
# ident = get_ident()
# return self.storage[ident][k]
# obj = Local()
# def task(arg):
# obj.val = arg
# # obj.xxx = arg
#
# print(obj.val)
# for i in range(10):
# t = Thread(target=task,args=(i,))
# t.start()

```

## 5 请求上下文执行流程

```python
看txt
```
原文地址:https://www.cnblogs.com/0B0S/p/13618743.html