首页 > 解决方案 > pythonify 或改进 python 参数验证

问题描述

我有一个接受单个参数的函数。有哪些方法可以改进参数验证?

这是可以传递的可能参数:

[
 {"type": "users", "level": 1, "name": "email@domain.com"},
 {"type": "groups", "level": 2, "id": 10001}
]

这是功能:

def function(properties: List[Dict]):
    for i in properties:
        if i["type"].lower() == 'users':
            if not all(['name', 'level']) in list(i):
                raise ValueError(
                        f"missing `name` or 'level' in type = {i['type']}")  # ValueError or SyntaxError
            if not isinstance(i['name'], str):
                raise TypeError(f" {i['name']} should be string")

        elif i['type'].lower() == 'groups':
            if not all(['id', 'level']) in list(i):
                raise ValueError(f"missing 'id' or 'level' in type = {i['type']}")
            if not isinstance(i['id'], int):
                raise TypeError(f" {i['id']} should be string")

感谢您在使此功能强大和优化方面提供的任何帮助。

标签: pythonpython-3.x

解决方案


您可以考虑将代码分解为更多功能:例如:

def handle_all(properties: List[Dict]):
    for item in properties:
        yield handle_one(**item)


def handle_one(type=None, level=None, name=None, id=None):
    if type.lower() == 'users':
        # ...
    elif type.lower() == 'groups':
        # ...

您甚至可以查看其他替代方案,例如基于 动态选择要调用的函数property['type'],并将其余参数传递给该函数。

def handle_user(name=None, level=None):
    # ...

def handle_group(id=None, level=None):
    # ...

functions = {
    'users': handle_user,
    'groups': handle_group,
}

def handle_all(properties):
    for item in properties:
        handler = functions[item.pop('type'))]
        yield handler(**item)

然后,您可以对所有这些进行注释,以确保传递正确的类型。


推荐阅读