博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flask(3)- flask中的CBV、werkzeug+上下文初步解读、偏函数和线程安全
阅读量:2240 次
发布时间:2019-05-09

本文共 2959 字,大约阅读时间需要 9 分钟。

一、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(
, 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(
, 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()

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

 

转载于:https://www.cnblogs.com/li-li/p/10247054.html

你可能感兴趣的文章
Servlet的生命周期
查看>>
Object中的getClass()返回的是当前运行的类
查看>>
加载驱动程序的方法
查看>>
深入理解java异常处理机制
查看>>
object类的基本方法
查看>>
回答阿里社招面试如何准备,顺便谈谈对于Java程序猿学习当中各个阶段的建议
查看>>
Dubbo分布式服务框架入门(附工程)
查看>>
两年Java开发工作经验面试总结
查看>>
作为Java面试官--谈谈一年来的面试总结
查看>>
两年Java程序员面试经
查看>>
面试心得与总结---BAT、网易、蘑菇街
查看>>
如何面试有2年java工作经验的应聘人员
查看>>
Java实现简单的递归操作
查看>>
面试Java程序员需具备的11个技能
查看>>
HashMap 和 HashTable 到底哪不同 ?
查看>>
Java实现简单的递归操作
查看>>
Struts2工作原理和执行流程图
查看>>
在线预览Word,Excel~
查看>>
hibernate延迟加载(get和load的区别)
查看>>
关于文件拷贝效率问题
查看>>