个人博客同步csdn
声明:
没怎么用过 flask,python也学的浅,如果有错或有更好的解决方案欢迎提出
1. 前言
flask中我目前获取请求参数都必须从request里面手动拿出来然后封装成我要的对象,觉得实在是太麻烦了,毕竟springboot中controller写了参数都会自动注入进去…
然后也对 Python 的装饰器比较感兴趣,所以就练手写了一下,目前能实现一些简单的类的注入
下面直接放代码!!
2. 装饰器
import functools
from flask import request
"""
根据类型和构造方法参数列表自动创建对象
"""
def init_object(type_class, **kwargs):
# 获取构造方法的参数列表
names = type_class.__init__.__code__.co_varnames
params = {}
# 从1开始是因为第0个是self,跳过
for i in range(1, len(names)):
name = names[i]
# 如果不存在就设为None
if name not in kwargs:
params[name] = None
else:
params[name] = kwargs[name]
# 构造对象
return type_class(**params)
"""
自动将请求参数注入到函数参数列表中
"""
def inject(**types):
def detect(fun):
co_names = fun.__code__.co_varnames
cnt = fun.__code__.co_argcount
co_names = co_names[:cnt]
@functools.wraps(fun)
def wrapper():
jsons = {}
args = request.args
if request.mimetype == 'application/json' and request.json is not None:
jsons = request.json
# 合并args和json参数字典
merge = dict(**args, **jsons)
# 函数参数字典
funParams = {}
# 合并请求后的参数字典
for key in types:
# 将请求参数内的变量用来构造
var = init_object(types[key], **merge)
# 构造完毕后删除合并字典
if key in merge:
del merge[key]
# 函数参数字典加入构造后的变量
funParams[key] = var
# 以函数参数字典为准,与函数参数列表进行合并
for key in merge:
if key not in funParams and key in co_names:
funParams[key] = merge[key]
return fun(**funParams)
return wrapper
return detect
3. flask 示例
import functools
from flask import Flask
from autoinject import inject_params
app = Flask(__name__)
class User:
def __init__(self, userId, userName):
self.userId = userId
self.userName = userName
@app.route('/', methods=['GET', 'POST'])
@inject(user=User)
def hello_world(user: User, a):
# vars用于获取对象中的成员变量
print(vars(user), a)
return "hello world"
if __name__ == '__main__':
app.run(debug=True)
4. Postman 演示
成功注入!!