Python语法学习记录(23):函数参数注释语法、访问函数注释【inspect块代码示例】 您所在的位置:网站首页 python中自定义函数的规则 Python语法学习记录(23):函数参数注释语法、访问函数注释【inspect块代码示例】

Python语法学习记录(23):函数参数注释语法、访问函数注释【inspect块代码示例】

2024-07-17 12:21| 来源: 网络整理| 查看: 265

1、简述

在 Python 3.x 中,增加了一个新特性:函数注释(Function Annotations),顾名思义,可做为函数额外的注释来用。

函数注释是一个可选功能,它允许在函数参数和返回值中添加任意的元数据。无论是 Python 本身还是标准库,都使用了函数注释,第三方项目可以很方便的使用函数注释来进行文档编写、类型检查、或者是其他用途。

在 Python 2.x 中,由于缺少对函数参数和返回值进行注释的标准方法,所以很多工具和库为了填补这一空白,使用了不同的方式:

自定义 decorator 自定义 docstring 格式 向函数对象添加自定义属性 显然,由于机制和语法的广泛差异,这会在一定程度上引起混乱。

为了解决这个问题,Python 3.x 引入了函数注释(详见:PEP-3107),旨在提供了一种单一的、标准的方法,来将元数据与函数参数和返回值相关联。

注意: 注释是完全可选的。

2、函数注释语法

函数注释作用是提高代码可读性,暗示传入参数及返回数据的类型。

函数注释两个部分:

参数注释:以冒号(:)标记,建议传入的参数类型返回值注释:以 ->标记,建议函数返回的类型

语法结构大体如下:

def funname(para1: expression, para2: expression = 5) -> expression: ...

expression 为函数注释。函数注释可以包含类型、帮助字符串,以及其他更多信息。一般为字符串表示注释,或变量类型名。

参数注释的伪语法中,参数看起来像:identifier [: expression] [= expression]。也就是说,参数注释总在其默认值之前。当函数定义被执行时,所有的注释表达式都被求值,就像默认值一样。参数列表后面可以跟一个 -> 和一个 Python 表达式。与参数的注释一样,在执行函数定义时,将对该表达式求值。但注意表达式就相当于注释所规定的的类型或者内容并非强制,也不会有相应的检查

示例 1: def addfun(a:"被加数"=11 , b:int=2)->"abc": return a+b if __name__ == "__main__": print(addfun(4,4))

image-20201019212700383

示例2:

来看一个例子,有一个函数 sum(),接受三个参数 a、b、c,并返回它们的和。

def sum(a, b: int, c: 'The default value is 5' = 5) -> float: return a + b + c

其中,第一个参数 a 没有注释,第二个参数 b 带有类型为 int 的注释,第三个参数 c 带有一个帮助字符串注释并且拥有默认值,返回值用类型 float 来注释。

调用 sum() 两次,一次使用 int,一次使用字符串:

def sum(a, b: int, c: 'The default value is 5' = 5) -> float: return a + b + c if __name__ == "__main__": print(sum(1, 2)) print(sum('Hello', ', ', 'Python!'))

显然,注释对函数的执行没有任何影响。在这两种情况下,sum() 都做了正确的事情,只不过注释被忽略了而已。

image-20201019213810347

3、访问函数注释

函数对象有一个名为 __annotations__ 的属性,它是一个映射(dict),用于将每个参数名(key)映射到其相关的注释(value)。

注意: 映射中有一个特殊的 key,叫做"return",仅当为函数的返回值提供注释时,才会显示该 key。

回到上述示例,并检查它的注释:

type(sum.__annotations__) sum.__annotations__ {'c': 'The default value is 5', 'return': , 'b': }

之所以选择 "return",是因为它不会与任何参数名冲突。"return"是 Python 中的一个关键字,任何使用"return"作为参数名的尝试都会引发 SyntaxError。

image-20201019214200221

4、多个内容注释

倘若,函数注释中要同时包含类型和帮助字符串,可以使用具有两个 key(例如:type 和 help)的 dict:

def div(a: dict(type=float, help='the dividend'), b: dict(type=float, help='the divisor (must be different than 0)')) -> dict(type=float, help='the result of dividing a by b'): """Divide a by b""" return a / b if __name__ == "__main__": print(div.__annotations__) print(div(5, 2))

image-20201019215351224

注意: 如果要包含更多的注释(示例中是 2 个),可以在 dict 中包含更多的 key:value 对。

5、动态注释

__annotations__ 是函数的一个属性,类型为 dict。由于dict 是可变的,这意味着,可以在程序运行时动态地修改注释。

假设,想知道是否使用了参数的默认值,或者想把所有的返回值都加起来。

def sum(a, b) -> 0: result = a + b sum.__annotations__['return'] += result return result if __name__ == "__main__": print("原始设置参数:",sum.__annotations__['return']) print(sum(1, 2)) print("第一次调用后参数:",sum.__annotations__['return']) print(sum(3, 4)) print("第二次调用后参数:",sum.__annotations__['return'])

image-20201019220034620

PS: 动态注释可以在函数内部完成,也可以由装饰器完成。

6、inspect模块

代码分析,发现隐藏BUG提供给第三方工具:inspect模块

inspect 模块 的作用

(1).对是否是模块,框架,函数等进行类型检查。

(2).获取源码

(3).获取类或函数的参数的信息

以下是官方文档说明:

inspect模块提供了几个有用的函数来帮助获取有关活动对象的信息,例如模块,类,方法,函数,回溯,框架对象和代码对象。 例如,它可以帮助您检查类的内容,检索方法的源代码,提取和格式化函数的参数列表,或获取显示详细回溯所需的所有信息。

import inspect import functools def dect(fn): @functools.wraps(fn) def _dect(*args,**kwargs): sig = inspect.signature(fn) params = sig.parameters #有序字典 keys = list(params.keys()) values = [_ for _ in params.values()] for i,m in enumerate(args): #args用tuple包装二元组的方式保存位置参数 #和注解进行比较 if values[i].annotation is not inspect._empty: if isinstance(m,values[i].annotation): print("正确:",keys[i],'==', m,",属于",values[i].annotation) else: print("不正确:",keys[i],'=', m,",不属于",values[i].annotation) else: print("没有检查需要:",keys[i]) for k,v in kwargs.items(): if params[k].annotation is not inspect._empty and isinstance(v,params[k].annotation): #业务需求应该是没有注解就不比较了 print(k,'===',v) ret = fn(*args,**kwargs) return ret return _dect @dect def add(x,y:int =7) -> int: #add = dect(add) return x + y add("1","2") add(1,2)

image-20201019231203071

LAST、参考文献

Python3 函数注释:参数中的冒号与箭头

python标准库中inspect 模块简单介绍

Python–参数注解



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有