繁体   English   中英

Python 装饰器用于检查返回类型:特别是检查嵌套的东西,如 List[List[List[str]]]

[英]Python decorator for checking the return type: Especially check for nested things like List[List[List[str]]]

我正在尝试编写我的一个 python 装饰器来进行类型检查。 它工作得很好,但在嵌套类型提示方面遇到了困难。 例如采取

@type_check
def fun(x: int) -> List[List[List[str]]]:
    return [[[str(x)]]]

fun(x=42)

我有一个装饰器,它评估 function 并检查实际返回值是否具有预期的类型:

import inspect
# inside the decorator
actual_result = func(*args, **kwargs)              # [[['42']]]
expected_result_type = spec.annotations['return']  # typing.List[typing.List[typing.List[str]]]

现在检查的挑战是[[['42']]]有类型typing.List[typing.List[typing.List[str]]] 我怎样才能做到这一点?

我发现, [[['42']]]只是简单地键入<class 'list'> ,它完全忽略了有关嵌套的信息。 我可以检查一下

if hasattr(expected_result_type, '__origin__'):
    expected_result_type = expected_result_type.__origin__

if expected_result_type is not None:
    assert isinstance(result, expected_result_type)
else: # None is kind of a special case
    assert result is expected_result_type

这适用于“外层”,但忽略嵌套类型提示。 有什么方法可以检查所有图层吗?

简单的答案是:

简单地递归到所有 arguments 像:

def type_check(value, annotation):
    if isinstance(annotation, type):
        return isinstance(value, annotation)
    elif annotation == typing.T or annotation == typing.Any:
        return True
    elif isinstance(annotation, typing._GenericAlias):
        if annotation.__origin__ == list:
            if not isinstance(value, list):
                return False
            inner_annotation = annotation.__args__[0]
            return all(type_check(val, inner_annotation) for val in value)

例子

>>> type_check(5, int)
True
>>> type_check([1, 2, 3], typing.List[int])
True
>>> type_check([1, 2, 3], typing.List[float])
False

你可以简单地在你的装饰器中使用它。 它可能会改进以处理 Dict、Tuple 和其他常见类型。

然而,这只是一个玩具示例,如果你想进行健壮的动态类型检查,你将不得不处理GeneratorCallableIterator等......这不仅非常复杂,而且在某些情况下完全不可能(例如 Iterators 可以'除非迭代,否则不会被检查)。

看看enforce 项目,它就是这样:使用装饰器的python 动态类型检查。 typing模块的源代码读起来也很有趣,但确实突破了动态自省的极限。

希望能帮助到你;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM