zoukankan      html  css  js  c++  java
  • 中间件、猴子补丁、蓝图、请求上下文执行流程

    ## 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
    ```
  • 相关阅读:
    认识ASP.NET 中的 AppDomain
    试验总结1 改变递归函数中的执行内容
    试验总结2 break与continue
    开篇的话
    01复杂度3 二分查找
    02线性结构2 一元多项式的乘法与加法运算
    01复杂度2 Maximum Subsequence Sum
    02线性结构4 Pop Sequence
    01复杂度1 最大子列和问题
    02线性结构1 两个有序链表序列的合并
  • 原文地址:https://www.cnblogs.com/0B0S/p/13618743.html
Copyright © 2011-2022 走看看