對比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()
總結:完美解決問題,採用了以空間換取時間的方法,爲每一個線程保存了一塊空間,使線程之間互相不受影響。