一、说明

1.1 关于注解

关于注解这个东西,最早是在大学学java的时候经常会看到某些方法上边@override之类的东西,一方面不知道其作用但另一方面似乎去掉也没什么影响,所以一直都不怎么在意。

今年去看开发的代码也看到很多注解,问其用途基本都和网上类似“为了开启XXX功能我们需要添加@XXX注解的”/”添加@XXX注解是为了开启XXX功能“,不知其原理感觉颇为难受所以自己来研究了一翻。

1.2 关于可变参数

所谓可变参数,最主要就是指传递给被调用函数的参数的个数是不定的。

可变参数应该来说是很常见的,比如C的标准main函数就写成int main(int argc, ** char argv),再比如很常用的print()函数就是最典型的可变参数函数。

但一方面在很长一段时间内并不能理解main函数其实和普通函数没什么区别,另一方面觉得print()是系统函数实现很复杂,所以一直都没弄懂如何实现可变参数应该传递。

1.3 关于注解和可变参数有什么关系

注解和可变参数,在感觉上是没什么关系的。但当我去实现注解,发现要让注解可作用于不同参数个数的函数时需要解决可变参数问题。

而且应当来讲注解作用于不同参数个数的函数是个普遍的需求,所以注解和可变参数关系还是关联很大的。

二、注解代码实现

2.1 被注解函数无参数

#一个用于进行修饰的函数#关键一:外层函数有且只有一个参数,该参数用于承接被修饰函数本身

defdecorate_function(need_decorate_function_name):defdecorated_function():#关键二:在调用被修饰函数前/后做些其他事情

print("calc staring...")#关键点三:原封不动地调用被修饰函数

need_decorate_function_name()print("calc finished...")#关键点四:在最后把修饰完后的函数return回去

returndecorated_function#一个简单的求合函数

@decorate_functiondefcalc_sum():

a= 1b= 2sum_value= a +bprint(f"{a} + {b} = {sum_value}")if __name__ == "__main__":

calc_sum()

最终执行结果如下:

2.2 被注解函数有参数

#一个用于进行修饰的函数

defdecorate_function(need_decorate_function_name):#关键点一:内层函数使用和被修饰函数完全一样的参数去承接即可

#当然参数名一不一样本来其实无所谓,但为了省事全都一样即可

defdecorated_function(a, b):print("calc staring...")#关键点二:内层函数将接收到的参数又再原封不动地传给被修饰函数即可

need_decorate_function_name(a, b)print("calc finished...")returndecorated_function#一个简单的求合函数

@decorate_functiondefcalc_sum(a, b):

sum_value= a +bprint(f"{a} + {b} = {sum_value}")if __name__ == "__main__":

calc_sum(1, 2)

最终执行结果如下:

2.3 被注解函数有返回值

#一个用于进行修饰的函数

defdecorate_function(need_decorate_function_name):defdecorated_function(a, b):print("calc staring...")#关键点一:承接好被修饰函数的返回值

result =need_decorate_function_name(a, b)print("calc finished...")#关键点二:在末尾将被修饰函数的返回值原封不动地向上层返回

returnresultreturndecorated_function#一个简单的求合函数

@decorate_functiondefcalc_sum(a, b):

sum_value= a +breturnsum_valueif __name__ == "__main__":

a= 1b= 2sum_value=calc_sum(a, b)print(f"{a} + {b} = {sum_value}")

执行结果如下:

2.4 被注解函数有多个且它们的参数个数不一致

#一个用于进行修饰的函数

defdecorate_function(need_decorate_function_name):#关键点一:使用*args, **kwargs承接所有参数

def decorated_function(*args, **kwargs):print("calc staring...")#关键点二:一模一样地直接把*args, **kwargs传给被修饰函数即可

result = need_decorate_function_name(*args, **kwargs)print("calc finished...")returnresultreturndecorated_function#一个简单的求合函数

@decorate_functiondefcalc_sum_2(a, b):

sum_value= a +breturnsum_value#一个简单的求合函数

@decorate_functiondefcalc_sum_3(a, b, c):

sum_value= a + b +creturnsum_valueif __name__ == "__main__":

a= 1b= 2c= 3sum_value_2=calc_sum_2(a, b)print(f"{a} + {b} = {sum_value_2}")

sum_value_3=calc_sum_3(a, b, c)print(f"{a} + {b} + {c} = {sum_value_3}")

执行结果如下:

2.5 在类内使用注解

classTest:#一个用于进行修饰的函数

#关键点一:坚定不移地认同,外层函数有且只有一个参数,该参数用于承接被修饰函数

defdecorate_function(need_decorate_function_name):#关键点二:坚定不移地认同*args, **kwargs可以承接所有参数,包括self在内

def decorated_function(*args, **kwargs):print("calc staring...")#关键点三:坚定不移地认同*args, **kwargs可以把所有参数传给被修饰函数,包括self在内

result = need_decorate_function_name(*args, **kwargs)print("calc finished...")returnresultreturndecorated_function#一个简单的求合函数

@decorate_functiondefcalc_sum_2(self, a, b):

sum_value= a +breturnsum_value#一个简单的求合函数

@decorate_functiondefcalc_sum_3(self, a, b, c):

sum_value= a + b +creturnsum_valueif __name__ == "__main__":

obj=Test()

a= 1b= 2c= 3sum_value_2=obj.calc_sum_2(a, b)print(f"{a} + {b} = {sum_value_2}")

sum_value_3=obj.calc_sum_3(a, b, c)print(f"{a} + {b} + {c} = {sum_value_3}")

执行结果如下:

三、可变参数实现本质

python中调用函数时,传递参数有两种方式,一种是以位置形式进行传递(如test(a)),一种是以“k=v”的的形式进行传递(如test(a=1))。同样的“k=v”形式必须位于位置参数之后。

(另外,python中定义一个函数其参数有类似的两种形式,一种是没有默认值的参数(位置参数,如def test(a)),一种是有默认值的参数(默认参数,def test(a=1))。另外默认参数必须处于位置参数之后。但一是我们这里参数传递并不需要关心函数定义时参数的形式)

使用的演示程序如下:

#一个简单的求合函数

defcalc_sum(a, b, c, d, e):

sum_value= a + b + c + d +ereturnsum_value#此函数只单纯调用calc_sum()

def call_calc_sum(a,*args,**kwargs):

sum_value= calc_sum(a,*args,**kwargs)returnsum_value

call_calc_sum(1, 2, 3, e=4, d=5)

3.1 从参数变为*args, **kwargs的过程

被调用函数通过以下步骤提取参数:

第一步,如果前面有非*args, **kwargs的参数,则在传来的参数中先分配给他。比如这里在*args前面有a,所以就把第一个参数值1赋给a。

第二步,将其他非k=v形式的参数,组成元组赋值为args。比如这是把下来的2,3组成(2,3)。

第三步,将其他的k=v形式的参数,组成字典赋值给kwargs。比如这里把e=4,d=4组成[‘e‘: 4, ‘d‘: 5]。

3.2 从*args, **kwargs变回具体参数的过程

被调用函数通过以下步骤提取参数:

第一步,如果开头有非*args, **kwargs的参数,则将按正常参数解析。如1赋给第一个参数a。

第二步,将元组参数按顺序分发给接下来的参数。如将2赋给下来的第二个参数b,再将3赋给下来的第三个参数c。

第三步,将字典参数,按设置的k/v分发给对应的参数。如按e=4赋给第五个参数e,按d=5赋值给第四个参数d。

python注解实现原理_Python3注解+可变参数实现相关推荐

  1. 注解 java 原理_Java注解基本原理

    注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量的去用注解,一时方便,而是代码更加简洁. 注解的语法比较简单,除了@符号的使用之外,它基本与Java固有语法一致.Java S ...

  2. Python基础教程:函数的可变参数

    在Python函数中,还可以定义可变参数. 如:给定一组数字a,b,c--,请计算a2 + b2 + c2 + --. 要定义出这个函数,我们必须确定输入的参数.由于参数个数不确定,我们首先想到可以把 ...

  3. python函数里面,一个*是可变参数的元祖,两个*是可变参数的字典

    python的函数中,有时会有类似*args,**keys这样的参数,代表的是可变参数,一个*表示元祖,两个*表示字典,就是说这个函数可以接受任何类型的参数,都不会报错,有些函数为了提高可用性,会加这 ...

  4. python求最大值最小值_Python求可变参数的最大值最小值以及参数个数

    求可变参数的最大值最小值以及参数个数 简介: 首先要做这个题,我们要使用函数来解决,这就要求我们要掌握函数的定义以及函数的调用.函数是一段具有特定功能的.可重用的,用来实现单一,或相关联功能的代码段. ...

  5. python线程池原理_Python3线程池ThreadPoolExecutor总结

    是什么 如何用 常用方法一:with ThreadPoolExecutor as t: t.submit import concurrent.futures import urllib.request ...

  6. python函数如何实现可变参数_【已解决】Python中实现可变参数的函数

    [问题] Python中,希望实现一个可变参数的函数. [解决过程] 相关代码如下:(extractOK, extractedBlogUser, generatedBlogEntryUrl) = ca ...

  7. Python 函数(可变参数)

    在python函数中,可以定义可变参数,顾名思义,可变参数就是,传入的参数是可变的 例如,给定一组数字a,b,c...  请计算a2 + b2 + c2 + -- 要定义出这个函数,我们必须确定输入的 ...

  8. x64 可变参数原理完全解析

    问题引子 众所周知,在 X64 下,函数参数都是尽量通过寄存器来传递的(浮点数使用专用的浮点数寄存器 xmm, 其他参数使用通用寄存器),只有 abi 里规定的这些寄存器用完之后,才使用栈来传递参数. ...

  9. Xiaoxia[PG] Python可变参数与标准输出的重定位

    Xiaoxia[PG] Python可变参数与标准输出的重定位 Python可变参数与标准输出的重定位 « Xiaoxia[PG] Python可变参数与标准输出的重定位 使用Python的内置函数p ...

最新文章

  1. LeetCode简单题之圆形赛道上经过次数最多的扇区
  2. 加工中心刻字宏程序_加工中心通用铣螺纹宏程序实例,千万别说你学不会!
  3. MFC_自定义事件响应
  4. Java串口包Javax.comm的安装
  5. link2001错误无法解析外部符号metaObject
  6. 2018高职计算机474分排名,2018年高职分类考试招生录取分数线出炉
  7. binaryviewer java_用java实现java的2进制文件字节序转换到C/C++的2进制文件字节序
  8. 计算任意两个圆的交点
  9. 大数据之-Hadoop之HDFS的API操作_网络拓扑_节点离客户端的距离计算---大数据之hadoop工作笔记0067
  10. 078 numpy模块
  11. 辗转相除法求最小公约数
  12. Java Web 学生选课管理系统
  13. 大学计算机第四版蒋加伏ppt,大学计算机基础 普通高等教育十一五 国家级规划教材 教学课件 作者 蒋加伏 王宇 第5章 Powerpoint 2003演示文稿制作基础.ppt...
  14. VNN结合金蝶Kis9.1专业版Sp1的应用及解决方案
  15. 全国计算机等级二级ACCESS数据库程序设计(更新完毕)
  16. iOS滤镜实现之LOMO(美图秀秀经典LOMO)
  17. 第1章思维导图图片版
  18. 顾连康复中心一个月费用?医保能报销吗
  19. 数据清理、转换、合并、重塑
  20. 基于Web实现网络拓扑图

热门文章

  1. 深入浅出统计学(十三)假设检验
  2. 读科研文献也能泄露隐私,用户发现爱思唯尔PDF阅读器收集用户信息
  3. 中秋节前,送一波福利
  4. 最新!2020世界一流大学学术排名出炉:北京大学、清华大学、中国人民大学表现卓越!...
  5. 把梯度下降算法变成酷炫游戏,这有一份深度学习通俗讲义
  6. 一文带你了解卷积神经网络基础,建议收藏
  7. 多所双一流高校通知将恢复正常上班!还有的为在校生开放实验室
  8. 操作系统学习:启动进入实模式
  9. 自然语言处理(NLP)之词义消歧(WSD)的简介与实现
  10. 爬虫之requests模块发送带header的请求