1. 程式人生 > >Pyhton全棧的知識點(5)

Pyhton全棧的知識點(5)

ren 定義 取數據 mar 傳遞數據 創建 xxxx tool after

1. 對於django來說,內部組件特別多,自身功能強大,有點大而全,而flask,內置組件很少,但是它的第三方組件很多,
    擴展性強,有點短小精悍,而它們之間也有相似之處,
  因為它們兩個框架都沒有寫sockte,都是基於wsgi協議做的,在此之外,flask框架中的上下文管理較為耀眼。
  
  相同點:它們兩個框架都沒有寫sockte,都是基於wsgi協議做的
  請求相關數據傳遞的方式不同:django:通過傳遞request參數取值
                flask: request的模塊
           組件不同:django組件多
                flask組件少,第三方組件豐富
    註意: 使用上下文管理機制
    
-threading.local()/greenlet.get_current()?---》Local的作用? 作用:為每個線/攜程程創建一個獨立的空間,使得線程對自己空間中的數據進行操作(數據隔離)。 應用:DBUtils中為每個線程創建一個數據庫鏈接時使用 -如何獲取一個線程的唯一標記:threading.get_ident() -再次根據線程唯一標記,設置一個大內存字典的key,值就是線程空間中的數據 -DBUtils線程池的模式也是為每個線程創建一個鏈接 -SQLAlchemy的create_engine也會創建線程池以供使用 2. session 兩個Local和LocalStack分別對應ctx和app_ctx 請求上下文管理(ctx):request,session 應用上下文管理(ap_ctx)
- 請求到來之後wsgi會觸發__call__方法,由__call__方法再次調用wsgi_app方法 - 在wsgi_app方法中: - 首先將 請求相關+空session 封裝到一個RequestContext對象中,即:ctx。 - 將ctx交給LocalStack對象,再由LocalStack將ctx添加到Local中,Local大字典結構: __storage__ = { 1231:{stack:[ctx] } }
- 根據請求中的cookie中提取名稱為session_id對應的值,對cookie進行加密+反序列化,再次賦值給ctx中的session -> LocalStack獲取Local中的數據後,視圖函數通過LocalProxy,獲取LocalStack中相對應的值 - 增刪改查 - 把session中的數據再次寫入到cookie中。 - 將ctx刪除 - 結果返回給用戶瀏覽器 - 斷開socket連接 3. 問題: 為什麽要把 ctx=request/session app_ctx = app/g 分開? 答:編寫離線腳本時,需要配置文件,而配置文件存放在app中,並不需要請求相關數據  所以把app和請求相關的數據分開。如果只是需要g傳遞數據,則在g的生命周期中完全夠用 在web runtime時,棧中永遠只有一個ctx,或者app_ctx; 在使用離線腳本時,則可能存在多個,但是數據並不會混雜,通過with語句和top取值(-1)可以分層次獲取 4. Flask中g的生命周期? 在請求觸發__call__調用wsgi_app時,生成app_ctx=AppContext(app,g) 在請求結束時app_ctx.pop()結束g 5. g和session一樣嗎? g是在有請求時被創建,請求結束時刪除,下次請求又是一個新的g session會被加密序列化寫入用戶cookie,下次請求解密反序列化就有 6. g和全局變量一樣嗎? 全局變量在程序啟動時只生成一次,有且只有這一個變量 g在請求時被生成,請求結束時被刪除,是臨時可創建變量 7.依賴的wsgi(服務器網關接口): werkzurg 8. 配置文件 可以設置一個跟Django差不多的settings配置文件,通過app.config.from_object("settings.xxx")路徑, 具體實現是通過importlib模塊和getattr反射找到“字符串路徑”,再引用配置相關信息 9. 路由系統 -基於裝飾器實現的路由系統 -endpoint,反向生成URL,默認函數名 -url_for("函數名" or endpoint)--------註意endpoint反向生成url時有同名, 需要導入import functools -> @functools.wraps(func) 保留原函數的原信息 -functool.partial 偏函數(減少用戶輸入函數參數) -動態路由:@app.route("/index/<int:nid>") 傳遞參數使用 10. 視圖 -基於反射區別method請求 -FBV 路由設置:@app.route("/xxxx") -CBV methods = ["GET",] decorators = ["wrapper"] 路由設置:app.add_url_rule("/xxx", None, UserView.as_view(aaa)) 11. 請求相關 # 請求相關信息 # request.method request.path # request.args request.full_path # request.form request.url # request.values request.files # request.cookies request.headers 12. 響應 響應體: return "字符串" return jsonify({"k1": "v1"}) return render_template("xx.html") return redirect("/xxxx") 定制響應體: -面向對象的封裝 obj = make_response("字符串") obj.headers["k1"] = "v1" obj.set_cookie("key", "value") return obj 設置全局訪問權限: @app.before_request def xxx(): if request.path == /login: return None if session.get(user): return None return redirect(/login) 13. 模板渲染 -基本數據類型:可以執行python語法 -傳入函數: -django, 自動執行 -flask, 需要手動加括號執行 -全局定義函數 @app.template_global() def xx(a1, a2): # {{sb(1,9)}} return a1 + a2 -添加撒選條件 @app.template_filter() def db(a1, a2, a3): # {{ 1|db(2,3) }} return a1 + a2 + a3 -模板繼承跟django差不多 -預定義模塊(不傳值看不見,傳值就啟動) -安全 - 前端: {{u|safe}} - 後端: MarkUp("asdf")       14. 閃現 -在session中存儲一個數據,讀取時通過pop將數據移除,獲取的值返回給用戶 15. 中間件 - call方法什麽時候觸發? - 用戶發起請求時,才執行。 16. 藍圖(blueprint) -目標:給開發者提供目錄結構 其他: - 自定義模板、靜態文件 - 某一類url添加前綴 - 給一類url添加before_request 17. 特殊裝飾器 -放在列表,循環執行 1. before_request (請求相關) 2. after_request 3. before_first_request 4. template_global (模板相關) 5. template_filter 6. errorhandler (可以自定義錯誤信息) 18.before_request的執行時機(源碼實現:存放在一個列表)Local執行之後,視圖執行之前 19. threading.local (DBUtils組件創建一個線程池) 20. 為什麽導入request,就可以使用? 每次執行request.xx方法時,會觸發LocalProxy對象的__getattr__等方法,由方法每次動態的使用 LocalStack去Local中獲取數據。 21.擴展: 1. flask-session 2. DBUtils 其他地方也可以使用 3. wtforms 4. sqlalchemy

Pyhton全棧的知識點(5)