写点什么

Python3 Note 函数注解

用户头像
awen
关注
发布于: 2021 年 06 月 01 日

函数注解

Python3.0,引入了用于 python 函数元注解的 Function Annotations 特性。

语法

定义函数的时候对参数和返回值添加注解:


    def foobar(a: int, b: "it's b", c: str = 5) -> tuple:        return a, b, c
复制代码


a: int 这种是注解参数c: str = 5 是注解有默认值的参数-> tuple 是注解返回值。
复制代码


注解的内容既可以是个类型也可以是个字符串,甚至表达式:


    def foobar(a: 1+1) -> 2 * 2:        return a
复制代码


那么如何获取我们定义的函数注解呢?至少有两种办法:


__annotations__:
复制代码


    >>> foobar.__annotations__    {'a': int, 'b': "it's b", 'c': str, 'return': tuple}
复制代码


inspect.signature:
复制代码


    >>> import inspect    >>> sig = inspect.signature(foobar)    >>> # 获取函数参数    >>> sig.paraments    mappingproxy(OrderedDict([('a', <Parameter "a:int">), ('b', <Parameter "b:"it's b"">), ('c', <Parameter "c:str=5">)]))    >>> # 获取函数参数注解    >>> for k, v in sig.parameters.items():            print('{k}: {a!r}'.format(k=k, a=v.annotation))         a: <class 'int'>    b: "it's b"    c: <class 'str'>    >>> # 返回值注解    >> sig.return_annotation    tuple
复制代码

示例

    # coding: utf8    import collections    import functools    import inspect            def check(func):        msg = ('Expected type {expected!r} for argument {argument}, '               'but got type {got!r} with value {value!r}')        # 获取函数定义的参数        sig = inspect.signature(func)        parameters = sig.parameters          # 参数有序字典        arg_keys = tuple(parameters.keys())   # 参数名称            @functools.wraps(func)        def wrapper(*args, **kwargs):            CheckItem = collections.namedtuple('CheckItem', ('anno', 'arg_name', 'value'))            check_list = []                # collect args   *args 传入的参数以及对应的函数参数注解            for i, value in enumerate(args):                arg_name = arg_keys[i]                anno = parameters[arg_name].annotation                check_list.append(CheckItem(anno, arg_name, value))                # collect kwargs  **kwargs 传入的参数以及对应的函数参数注解            for arg_name, value in kwargs.items():               anno = parameters[arg_name].annotation               check_list.append(CheckItem(anno, arg_name, value))                # check type            for item in check_list:                if not isinstance(item.value, item.anno):                    error = msg.format(expected=item.anno, argument=item.arg_name,                                       got=type(item.value), value=item.value)                    raise TypeError(error)                return func(*args, **kwargs)            return wrapper        @check    def foobar(a: int, b: str, c: float = 3.2) -> tuple:        return a, b, c
复制代码


  • 场景

参考文献

用户头像

awen

关注

Things happen for a reason. 2019.11.15 加入

还未添加个人简介

评论

发布
暂无评论
Python3 Note 函数注解