类型注解和参数类型检查实现

本文探讨了Python 3.5及以后版本中引入的函数注解特性,包括参数和返回值类型注解,以及如何利用inspect模块进行类型检查。通过示例展示了注解在代码分析和类型验证中的应用。

python属于动态语言使用之前不需要事先定义,只有执行的时候才能直到变量的类型。

函数注解 Function Annotations

python 3.5后增加语法

  • python3.5引入
  • 对函数的参数进行类型注解
  • 对函数的返回值进行类型注解
  • 只对函数参数做一个辅助的说明,并不对函数参数进行类型检查
  • 提供给第三方工具,做代码分析
  • 函数的注解信息,保存在__annotations__属性中
def add(x:int,y:int)-> int:
        return x+y

在这里插入图片描述
在这里插入图片描述
注解并未强制性的约束,只是一个注解

python 3.6提供语法
r:list=add([4],[5])
在pycharm中再次引用r会有提示
查看help问文档
在这里插入图片描述

业务应用
  • 函数参数类型检查
  • 思路
    - 函数参数的检查,一定是在函数外,如要把检查代码侵入到函数中
    - 函数应该作为参数,传入到检查函数中
    - 检查函数拿到函数传入的实际参数,与形参声明形成对比
    - _annotations_属性是一个字典,其中包括返回值类型的声明。假设要做位置参数的判断无法和字典中的声明对应。使用inspect模块
  • inspect模块
    • 提供获取对象信息的函数,可以检查函数和类、类型检查
      检测输入的与参数注解是否相同
inspect模块
  • signature(callable),获取签名(函数签名包含一个函数的信息,包括函数名、它的参数类型、它所在的类和名称空间及其他信息)
import inspect
def add(x:int,y:int,*args,**kwargs)->int:
    return x+y
sig=inspect.signature(add) #获取函数参数注解
print(sig)
type(sig)
print(sig.return_annotation) #返回值的注解
print(sig.parameters)   #返回函数注解的有序字典
print(sig.parameters['y'],type(sig.parameters['y']))
print(sig.parameters['x'].annotation)
print(sig.parameters['args'])
print(sig.parameters['args'].annotation)
print(sig.parameters['kwargs'])
print(sig.parameters['kwargs'].annotation)

parameter对象

  • 保存在元组中,是只读的
  • name,参数的名字
  • annotation,参数的缺省值,可能是没有定义
  • empty,特殊的类,用来标记default属性或者注释annotation属性的空值
  • kind,实参如何绑定到形参,就是形参的类型
    • POSITIONAL_ONLY,值必须是位置参数提供
    • POSITIONAL_OR_KEYWORD,值可以作为关键字或者位置参数提供
    • VAR_POSITIONAL,可变位置参数,对应*args
    • KEYWORD_ONLY,keyword-only参数,对应或者args之后出现的非可变关键字参数
    • VAR_KEYWORD,可变关键字参数,对应**kwargs
在这里插入代码片

import inspect
from inspect import Parameter
def add(x,y:int=1)->int:
       return x+y
def check(fn):
    def wrapper(*args,**kwargs):
        sig=inspect.signature(add)
        params=sig.parameters
        values=list(params.values())
        keys=list(params.keys())
        #for i,x in enumerate(args):
            #if not isinstance(x,values[i].annotation) :
                #raise Exception('Wrong param={}{}'.format(keys[i],x))
        flag=True
        for x,(k,v) in zip(args,params.items()):
            if v.annotation !=inspect._empty and not isinstance(x,v.annotation):
               #raise Exception('Wrong param={}{}'.format(k,x))
                flag=False
        for k,v in kwargs.items():
            if not isinstance(v,params[k].annotation)and params[k].annotation !=inspect._empty:
                #aise Exception('Wrong param={} {}'.format(k,v))
                flag=False
        if not flag:
            r='输入有问题'
            return r
        else:
            ret=fn(*args,**kwargs)
            return ret
           
        return ret
    return wrapper
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值