• chapter5.3类型注解及习题


    函数定义的弊端

    动态语言的弊端,不能事先声明类型,赋值可以是不同的类型,只有在运行时才能发现

    动态语言的灵活的特性也是弊端

    为解决这些问题而使用类型注解,但也只是声明,并不能强制约束

      难发现,问题只有使用时才能发现,

      难使用,函数使用者并不能知道数据类型

    Documentation string文档说明,def后的三引号内的内容,pychram这些工具可以帮助你创建说明,惯例,不是强制标准

    函数注解Function Annotations

    def add(x:int,y:int) -> int,约定,不是强制性约束

      Python3.5引入

      对函数进行类型注解,返回值也可以注解

      并不会对参数进行类型检查

      只是说明性的辅助,并不会对参数检查

      提供给第三方工具,做代码分析,发现bug隐藏,例如 pychram会在类型错误时改变变量颜色

    函数注解的信息,保存在 fn.__annotations__

      函数的注解必不可少,

      可以来类型检查,通过编译器

      判断实参和形参的类型是否相同

    变量注解

      3.6以后的版本可以对变量注解

    函数参数类型检查的思路

    参数检查一定在函数外

    函数作为参数传入,检查函数拿到函数的实参,与形参的声明做对比

    fn.__annotations__属性是一个字典,包括返回值类型的声明,想要判断位置参数,就无法和字典对应,要引入inspect模块

    inspect模块

    提取获取对象信息的函数,可以检查函数的类

    import.inspect 

    sig = inspect.signature(foo)  获取签名,函数签名包括函数的信息,函数名,参数类型,他所在空间及类和其他信息。

    inspect 下有许多判断方式,例如

    isfunction(add)  是否是函数,

    ismethod(add)  是否是类方法

    isgenerator(add)  是否是迭代器

    isgeneratorfunctions(add)  是否是生成器函数

    isclass(add)  是否是类

    ismodule  是否是模块

    isbuiltin  是否是内建函数

    getdoc  获取函数文档

    更多可查看inspect模块

    sig.parameters  获取有序字典,包含参数类型声明,有序字典的key是形参,value是类型声明

    Parameters   保存在元组中,是只读的

      name   参数名字

      annotations  参数注解,可能没有定义,

      default  参数缺省值,可能没有定义

      empty   特殊的类,用来标记default属性或者注释annotation属性的空值

      kind  形参的类型

                       

    给一个函数加强功能,要求能检查用户输入是否符合参数注解的要求

    def check(fn):
        def wrap(*args,**kwargs):
            sig = inspect.signature(fn)#获取签名
            params = sig.parameters#获取参数注解
            value = list(params.values())
            for i,m in enumerate(args): 
                param = value[m]#判断位置参数
                if  param.annotation is not param.empty and not isinstance(m,value[i].annotation):
                    raise TypeError
                #else:
                    #print('ok')
            for k,v in kwargs.items():##判断keyword参数
                if params[k].annotation is not param.empty and not isinstance(v,params[k].annotation):
                    raise TypeError
                #else:
                    #print('okk')
    
            ret = fn(*args,**kwargs)
            return ret
        return wrap
    
    @check
    def add(x:int,y:int)->int:
        ret = x+y
        return ret
    add(1,y=2)
  • 相关阅读:
    Django(二)
    VSCode写Django的坑
    AXF—个Django项目
    Linux
    安装软件方面的问题及解决方法杂烩
    Python
    环境搭建
    Django(一)
    关于excel表
    (十)selenium实现微博高级搜索信息爬取
  • 原文地址:https://www.cnblogs.com/rprp789/p/9550524.html
Copyright © 2020-2023  润新知