flask專案重構總結(一):這一階段的重構主要集中在介面返回碼的格式統一上,優化了臃腫的各種判斷及try-exception 機制。
主要思路,使用裝飾器來封裝常用**;使用python的exception機制,自定義一些exception,在恰當的地方主動丟擲異常,然後在頂層再catch住,進行統一的handle處理。
在views.py檔案裡,我們都要檢查url裡的引數,原來寫法如下:
(__init__.py)
def checkparam(requirefields, param):
for i in requirefields:
if -1 == param.get(i, -1):
return false
return true
(views.py)
if not checkparam(["company_name", "sign", "userid"], param):
return 'missing param'這種寫法使得「missing param」 很分散,每個介面都要複製一遍**使得**非常臃腫,並且增加了「missing param」訊息體封裝的難度。針對這兩個問題,我們採用了如下方法來重構
參考了文雨寫的@frequency_limit,將檢查param和sign的方法抽離出來:
def frequency_limit(func):
@wraps(func)
def check_frequency():
userid = request.args.get('userid')
if not r.exists(userid):
raise sequee_exceptions.invaliduser
if int(r.get(userid)) <= 0:
raise sequee_exceptions.accesslimitationexception
r.decr(userid)
return func()
return check_frequency
def check_params_and_sign(func):
@wraps(func)
def check_it():
param = request.args
checkparam(["company_name", "sign", "userid"], param)
checksign(param.get("company_name"), param.get("userid"), param.get("sign"))
return func()
return check_it這樣,在使用時直接在每個函式的前面加上標籤就可以使用:
@app.route('/icp_url/', methods=['get'])
@frequency_limit
@check_params_and_sign
def icp_url():
……上面將checksign和checkparam 封裝後也引入了新的問題,怎麼恰當的將signerr和 paramerr返回呢,怎麼在寫**時盡量少些try-exception呢?
這裡我們借用exception機制來實現:
首先在sequee_exception.py檔案裡定義我們會用的異常,這裡拿invalidparamexception舉例。
(sequee_exceptions.py)
class invalidparamexception(exception):#自定義invalidparamexception,繼承自exception
def __init__(self):
exception.__init__(self)(sequee_web\__init__.py)
def checkparam(requirefields, param):
for i in requirefields:
if -1 == param.get(i, -1):#如果缺少param,則丟擲異常
raise sequee_exceptions.invalidparamexception
passflask 提供了異常處理的機制@app.errorhandler(exception)括號裡指明該方法handle的異常型別。這裡用了所有的異常父類-exception
@app.errorhandler(exception)
def hand_errs(e):
logging.error(traceback.format_exc())
# 引數錯誤
if type(e) == sequee_exceptions.invalidparamexception:
return json_message.err(json_message.invalid_param_err_message)
# 簽名錯誤
elif type(e) == sequee_exceptions.invalidsignexception:
return json_message.err(json_message.invalid_sign_err_message)
# 使用者名稱錯誤
elif type(e) == sequee_exceptions.invaliduser:
return json_message.err(json_message.invalid_user_err_message)
# 未授權使用者
elif type(e) == sequee_exceptions.unauthorizedexception:
return json_message.err(json_message.unauthorized_err_message)
# 訪問達到上限
elif type(e) == sequee_exceptions.accesslimitationexception:
return json_message.err(json_message.access_limitation_message)
# 內部錯誤,發郵件
send_alert_email_to(mail_receive, mail_cc, traceback.format_exc())
return json_message.err(json_message.internal_err_message)這樣,在一般的邏輯裡就不用考慮各種判斷和檢測了。同時**也簡潔不少:
最後的效果如下:
@app.route('/edu/school_common/', methods=['get'])
@frequency_limit
@check_params_and_sign
def school_common_info():
logging.debug('searching school_common info....')
param = request.args
db = mysql.mysql(mysql.mysql_conf["data_engine"])
conn = db.connect()
auth = checkuser(param.get("userid"), conn, 'school_common')
data = edu_query.query_edu(param.get("school_name"), 'putonggaoxiaobiao', conn) # 有查資料庫的許可權,可以查庫了
if auth == 1: # 全部資料可讀
return json_message.ok(data)
else: # 僅能讀取部分資料,將所有結果過濾後返回
return json_message.ok(filter_data_by_auth(data))
flask 專案總結
一,模組化的分離!1,增加配置檔案 db 是指的是變數名稱!migratecommand指的是遷移 manager.add command db migratecommand 4,setting檔案之中通過繼承與增加特殊屬性!class developmentconfig congig 增加額外的屬...
專案重構總結 1
到今天為止,webgate 專案重構 初步完成。還需要實現的功能有 1 修改,重置密碼功能。2 修改 page 功能。3 外部專案引入的jar 包。4 首頁 優化。重構一共經歷了 7 個周。第一周,看基本的 登入功能 實現思路。第二週,看兩個專案的配置,並開始配置。第三週,基本配置實現 核心資料表 ...
專案重構實踐 一
size medium 經典重構的書籍已經敘述了很多需要重構的事情,但是很多時候書籍規書籍,實踐規實踐,到底搞清楚沒有,還是實際專案中來得實在,真實。真實專案重構 重構一 專案中把很多前期看起來差不多的邏輯,比如處理流程相同,資料具有相似性,剛開始寫action,把這些全部都寫在乙個action裡面...