zoukankan      html  css  js  c++  java
  • 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))
      # 6
      # 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()

        总结:完美解决问题,采用了以空间换取时间的方法,为每个线程保存了一块空间,使线程之间互相不受影响。

  • 相关阅读:
    Spring基础知识
    Hibernate基础知识
    Struts2基础知识
    在eclipse里头用checkstyle检查项目出现 File contains tab characters (this is the first instance)原因
    java后台获取cookie里面值得方法
    ckplayer 中的style.swf 中的 style.xml 中的修改方法
    java hql case when 的用法
    Windows下Mongodb安装及配置
    Mongodb中经常出现的错误(汇总)child process failed, exited with error number
    Mac 安装mongodb
  • 原文地址:https://www.cnblogs.com/li-li/p/10247054.html
Copyright © 2011-2022 走看看