Python3 Dict(Json)Validate验证器 一时兴起想试试看python做一个类似tp框架的Validate验证器。

声名

初学Python,代码很糙,只是为了记录和大家相互探讨一下改进的办法。

想法

最近做Python处理的Dict和Json数据太多了,一个一个的判断in太麻烦了,于是想试试看能不能用自己的想法实现一个类似Validate验证器的东西。 这份代码说是验证器太草率了。
主要是针对Dict进行值的验证。

代码

class D_JValidator:
    """简易验证器
        :rules 验证规则
            {
                "name.phone":[
                    {
                        'type': 'require',
                        'message': '手机必须填写'
                    }
                ],
                "cl1.0.name":[
                    {
                        'type': 'require',
                        'message': '名称必须'
                    },{
                        'type': 'str',
                        'message': '名称必须是字符串'
                    }
                ]
            }
    """
    def __init__(self, rules:dict) -> None:
        if not rules:
            raise Exception("rules is must!")
        if not isinstance(rules, dict):
            raise Exception("rules is Only dict!")
        self.rules = rules

    def _dict_have_key(self, Data, nodes:str) -> bool:
        """判断dict里是否有节点路径"""
        if not isinstance(Data, (Dict,List)):
            raise Exception("Data is Only Dict/List!")
        if not isinstance(nodes, str):
            raise Exception("nodes is Only str!")
        # 存储dict下一个传递信息
        Cache = None
        # 拆分节点路径
        nodes_list = nodes.split(".")
        # 获取当前元素的类型
        now_node_type = str(type(Data))
        # 判断节点是否是数字
        if nodes_list[0].isdigit():
            # 判断当前元素是否是list类型,因为节点是下标。 同时判断node有没有在下标范围内。
            if not now_node_type.startswith("<class 'list'>") or (len(Data) - 1) < int(nodes_list[0]):
                return False
            Cache = Data[int(nodes_list[0])]
        else:
            # 直接判断当前的节点名称在不在Data中
            if nodes_list[0] not in Data:
                return False
            Cache = Data[nodes_list[0]]
        # 递归下一层
        if len(nodes_list) >= 2:
            nodes_list.pop(0)
            return self._dict_have_key(
                Data=Cache,
                nodes='.'.join(nodes_list)
            )
        return Cache
    
    def _check_rule(self, Data, rule, node) -> bool:
        """解析验证规则及验证数据是否符合验证规则"""
        # 判断Data为False说明节点压根不存在。
        if not Data:
            # 只需要关注rule是不是require。
            if rule['type'] == 'require':
                raise Exception(rule['message'])
            else:
                return True
        # 规则验证
        if rule['type'] == 'require':
            # 验证数据是不是为空, 如果是str先去掉空格
            if isinstance(Data, str):
                Data = Data.strip()
            if not Data:
                if 'message' in rule and rule['message']:
                    raise Exception(f"{node}: {rule['message']}")
                else:
                    raise Exception(f"{node} is require")
        elif rule['type'] == 'int':
            # 验证数据是不是int
            if not isinstance(Data, int):
                if 'message' in rule and rule['message']:
                    raise Exception(f"{node}: {rule['message']}")
                else:
                    raise Exception(f"{node} is not int")
        elif rule['type'] == 'str':
            # 验证数据是不是str
            if not isinstance(Data, str):
                if 'message' in rule and rule['message']:
                    raise Exception(f"{node}: {rule['message']}")
                else:
                    raise Exception(f"{node} is not str")
        return True

    def check(self, Data:dict):
        """验证
            :Data 验证的数据
        """
        if not isinstance(Data, dict):
            raise Exception("Data is Only dict!")
        # 循环验证规则
        for rule in self.rules:
            # 遍历全部的验证规则进行逐条判断
            for ruls_node_path in self.rules:
                # 判断路径节点是否存在
                Dict_Child = self._dict_have_key(
                    Data=Data,
                    nodes=ruls_node_path
                )
                # 遍历验证规则
                for rule_type in self.rules[ruls_node_path]:
                    self._check_rule(Dict_Child, rule_type, ruls_node_path)
if __name__ == "__main__":
	data = {
        "s2": "1"
    }

    rules = {
        "s.0":[
            {
                'type': 'str',
                'message': '必须是字符串'
            }
        ],
        "s2":[
            {
                'type': 'int',
                'message': '必须是数字'
            },{
                'type': 'require',
                'message': '必须有值'
            }
        ]
    }
    V = D_JValidator(
        rules=rules
    )
    V.check(
        Data=data
    )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值