zoukankan      html  css  js  c++  java
  • python 参数注解inspect


    # 静态语言:编译过程中会检查,会发下问题
    # 动态语言:只有在运行时才会发现问题
    # 1 由于编译期间不做任何检查,直到运行期间我呢提才会暴露
    # 2 函数使用者并不知道参数类型的时候,容易传错参数类型

    # 函数注解:给函数的形参一个类型,并有指向的return值
    # python3.5开始引入
    # 可以用于第三方工具(如:pycharm)提示是否有return
    # 3.6可以对变量进行注解,如:i:int = 3

    def add(x:int, y:int) -> int: # 声明规范是整数相加,并不强制形参类型
    '''
    This is add function
    :param x: int
    :param y: int
    :return: int
    '''
    return x + y

    print(add(4, 10))
    print(add(4.0, 5.0))
    print(add('abc', 'd'))

    # 业务应用
    # 检查实参类型
    # __annotations__是一个字典,其中包括返回值类型的声明。
    # inspect模块:提供回去对象信息的函数,可以检查函数和类、类型检查
    # signature(callable)函数,可以获取签名(函数签名包含了一个函数的信息,包括:函数名、参数类型、函数所在的类和名称空间及其他信息)

    import inspect

    def add(x:int, y:int, *args, **kwargs) -> int:
    '''
    This is add function
    :param x: int
    :param y: int
    :return: int
    '''
    return x + y

    print('0 ', add.__annotations__) # 普通字典
    sig = inspect.signature(add) # 拿到add函数签名((x:int, y:int, *args, **kwargs) -> int)
    print('---------------------')
    print(sig)
    print('1 params: ', sig.parameters) # 返回OrderedDict(有序字典)
    print('2 return: ', sig.return_annotation) # 返回值注解
    print('3 ', sig.parameters['x'])
    print('4 ', sig.parameters['x'].annotation) # 参数注解
    print('5 ', sig.parameters['args'])
    print('6 ', sig.parameters['args'].annotation) # 空类型 inspect._empty
    print('7 ', sig.parameters['kwargs'])
    print('8 ', sig.parameters['kwargs'].annotation) # 空类型 inspect._empty

    # inspect模块
    # inspect.isfunction(add) 是否是函数
    # inspect.ismethod(add) 是否是类的方法
    # inspect.isgenerator(add) 是否是生成器对象
    # inspect.isgeneratorfunction(add) 是否是生成器函数
    # inspect.isclass(add) 是否是类
    # inspect.ismodule(inspect) 是否是模块
    # inspect.isbuiltin(print) 是否是内建对象

    # inspect模块 - parameter对象
    # 保存在元组中,只读 OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">), ('args', <Parameter "*args">), ('kwargs', <Parameter "**kwargs">)])
    # name 参数名
    # annotation 参数注解,可能没有定义
    # default 参数缺省值,可能没有定义
    # empty 特殊的类,用来标记default属性或者注释annotation属性的空值
    # kind 实参如何绑定到形参
    # POSITIONAL_ONLY 值必须是位置参数提供
    # POSITIONAL_OR_KEYWORD 值可以作为关键字或者位置参数提供
    # VAR_POSITIONAL 可变位置参数,对应*args
    # KEYWORD_ONLY keyword_only参数,对应*或者*args之后出现的非可变关键字参数
    # VAR_KEYWORD 可变关键字参数,对应**kwargs

    def add2(x, y:int=11, *args, z, t=10, **kwargs) -> int:
    return x + y

    sig = inspect.signature(add2)
    print('================================')
    print('1 ', sig)
    print('2 params ', sig.parameters)
    print('3 return ', sig.return_annotation)
    for i, item in enumerate(sig.parameters.items()):
    name, param = item
    print(i+1, name, ' ', param.annotation, ' ', param.kind, ' ', param.default)
    print(param.default is param.empty, end=' ')

    # 装饰器
    from functools import wraps
    def checker(fn):
    @wraps(fn) # Decorator factory
    def wrapper(*args, **kwargs):
    # 检查实参
    print(args, kwargs)
    sig = inspect.signature(fn)
    params = sig.parameters # 有序字典
    # 位置参数检查
    param_list = tuple(params.keys()) # 转换成有序的元组
    for i, v in enumerate(args):
    k = param_list[i] # 拿到key
    if isinstance(v, params[k].annotation): # 根据key拿到注解
    print(v, ' is ', params[k].annotation)
    else:
    print(v, ' is not ', params[k].annotation)
    # 关键参数检查
    for k,v in kwargs.items():
    if isinstance(v, params[k].annotation):
    print(v, ' is ', params[k].annotation)
    else:
    errstr = '{} {} {}'.format(v, 'is not', params[k].annotation)
    print(errstr)
    raise TypeError(errstr) # 抛出异常
    result = fn(*args, **kwargs)
    return result
    return wrapper

    @checker
    def add3(x:int, y:int=8) -> int:
    return x + y

    print('================================')
    print(add3(4, y=5))
    add3('abc', 'bcd')
    print(add3(4))
  • 相关阅读:
    移动端链接、点击事件、输入框去除背景高亮
    Quartz.Net与MVC结合定时任务
    Win10上使用SVN遇到的一些问题
    Win7上的ASP.NET MVC3项目在Win10上运行的一个坑
    《SQL必知必会》学习笔记(二)
    《SQL必知必会》学习笔记(一)
    数据库知识总结(表结构操作)
    搭建三层架构(ASP.NET MVC+EF)
    python线程中的全局变量与局部变量
    ADO.NET Entity Framework学习笔录(一)
  • 原文地址:https://www.cnblogs.com/lizitest/p/9658001.html
Copyright © 2011-2022 走看看