zoukankan      html  css  js  c++  java
  • flask 第四章 偏函数 Local空间转时间 myLocalStack RunFlask+request 请求上下文

    1 . 偏函数 (partial)

    from functools import partial
    
    def func(*args,**kwargs):
        a=args
        b=kwargs
        return  a,b
    
    new_func=partial(func,1,2,3,4,a=3,b=5)
    ret=new_func()
    print(ret)
    

      最终得到的结果为: ( (1, 2, 3, 4) , {'a': 3, 'b': 5} )

      我理解的意思为: 将1,2,3,4,a=3,b=5传入func中去执行函数.

    其实就是 :往函数里传一个值不执行,返回一个新函数

    2.ThreadingLocal线程安全 空间转时间

    我们之前学的线程并发是这样的

    from threading import Thread 
    import threading
    class foo(object): pass f=foo() def func(a): f.num=a time.sleep(1) print(f.num,threading.current_thread().ident) for i in range(10): t=Thread(target=func,args=(i,)) t.start()

      但是这样我们打印的结果为

           

      原因是线程的创建速度是很快的(一瞬间),在第一个a进入函数执行时,睡眠了1秒,io切换到下一个时,又睡眠,直到最后一个进入函数,第一个a还在睡眠.当第一个结束睡眠的时候,num已经变成了最后一个值,所以每一个num都变成了最后一个数字9.

    解决方法:(只要在类中继承一个local即可)

    from threading import local
    import threading
    
    class Foo(local):
       pass
    
    f=Foo()
    
    def func(i):
        f.num=i
        time.sleep(1)
        print(f.num,threading.current_thread().ident)
    
    for i in range(10):
        t=Thread(target=func,args=(i,))
        t.start()
    

    3.myLocalStack

    import time
    from threading import Thread,local
    import threading
    
    class MyLocalStack(local):
        stack={}
        pass
    
    mls=MyLocalStack()
    
    def func(i):
        a=threading.current_thread().ident
        mls.stack[a]=[f'r{i+1}',f's{i+1}']
        time.sleep(1)
        print(mls.stack[a].pop(),mls.stack[a].pop(),a)
        
        mls.stack.pop(a)
        print(mls.stack,a)
    
    
    if __name__ == '__main__':
    for i in range(10):
        t=Thread(target=func,args=(i,))
        t.start()
    

    4.RunFlask + request

      视图函数 : 根据一个路由地址指向一个函数,这个函数就叫视图函数

       app.run()的原理:   

        app.run()实际上执行的是app里面的run_simple方法,
        而run_simple方法调用的是里面的__call__()方法,而__call__中返回了一个wsgi_app()方法
        run_simple方法里面需要的参数有(host,port,func,**options)
        参数:
          host : 服务器的ip地址
          port : 服务器端口
          func : 当请求过来的时候,执行func函数
          options : 传参参数

    具体实例代码如下:

    from werkzeug.serving import run_simple
    from werkzeug.wrappers import Response,Request
    
    @Request.application
    def app(req):
        if req.path == '/login':
            return login(req)
        return Response('200 OK')
    
    def login(res):
        return Response('欢迎来到登陆页面')
    
    run_simple('127.0.0.1',8888,app)
    

      req的意思就是request,他是werkzeug里面的用法,记住就行

    5.请求上文

    请求上文的意思是: 你怎么将app,request,session放进去的

    首先我们要清楚,run方法实际上执行的是__call__方法,而通过源码我们发现__call__实际上返回的是一个wsgi_app的方法

    返回到wsgi_app中

    我们得到了ctx返回了一个request_context对象,对象里面有 --> app, request , session

     

    最后得到结果:  top是LocalStack中的top方法

     

    到这里我们回顾之前一个学习的知识:

    class Foo(object):
        def __call__(self, *args, **kwargs):
            print("我是可以执行的对象")
    
        def __setattr__(self, key, value):
            print(key,value)
    
        def __getattr__(self, item):
            print(item)
            
    f=Foo()
    

    #对象加括号 : 调用哪个__call__方法
    f.num #这里实际上执行的是__getattr__方法,如果我们在上面没有写这个函数,那么会报错 #以上打印的结果为 num f.num=1 #这里实际上执行的是__setattr__方法 #以上打印的结果为 num , 1

      所以在上面我们发现 _local.stack[-1] ,所以我们是不是要找_local是不是有__getattr__方法呀

      所以最后我们得到的 top结果为 None.

     最后返回的rv: 

    到这里,请求上文也就结束了

    6.请求下文

    请求下文是你怎么将app,request,session拿出来调用的

      请求下文是在你执行视图函数的时候才开始运行的

      请求下文是执行函数的时候,request.方法或者使用到session的时候才到了请求下文的内容

    因为我们之前request.method 所以执行了__getattr__方法

     

  • 相关阅读:
    杂项
    hdu 2094
    hdu acm 1004
    android 重装sdk或者系统的时模拟器出现can open ****
    使用Java模拟操作系统高优先级算法
    各种语法解释及用法
    枚举与结构
    闭包
    socket
    异常
  • 原文地址:https://www.cnblogs.com/zty1304368100/p/10696481.html
Copyright © 2011-2022 走看看