Flask&&人工智能AI --3

1、flask中的CBV

  对比django中的CBV,咱们来看一下flask中的CBV怎么实现?html

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方法中指定。django

2、werkzeug + 上下文初步解读

       经过查看源码,咱们知道app.run() 方法实际上是执行了run_simple() 方法,源码以下:flask

  咱们能够经过下面一段代码探究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执行了,再看咱们以前写的代码:app

from flask import Flask, ...

  app = Flask(__name__)

  ......
  
  app.run(debug=True)         # app 是flask的实例化对象

 这里重点分析app.run() 都干了什么?ide

  首先,执行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方法,源码以下:post

 

  request_context() 方法源码以下,其中的self仍然是Flask的实例化对象app:url

 

  RequestContext是一个类,它的__init__方法源码以下:

 

  本篇暂时解读到这里,下篇继续解读。

3、偏函数和线程安全

一、偏函数就是把前边的值传进来可是不执行

  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)
  # 新函数不加括号不执行

二、线程安全

  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()

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

相关文章
相关标签/搜索