Python装饰器学习笔记,将 flask请求参数自动注入到函数参数列表中

个人博客同步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 演示

在这里插入图片描述
在这里插入图片描述
成功注入!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值