输出函数调用信息

【问题描述】j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

请设计一个函数修饰器,使之能输出函数的调用信息,包括函数名、参数值和返回值。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

输出函数调用信息输出结果:j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

multiply(4,b=7)返回值:28j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

备注:multiply是函数名,第1个参数值为4,第2个参数名为b,值为7,函数的返回值为28。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

【题前思考】j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

根据问题描述,填写表5-3-1。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

表5-3-1 问题分析j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

输出函数调用信息j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

【解题思路】j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

假设函数名为fun,则其属性__name__就可以取得与函数名相同的字符串“fun”。函数的参数分为位置参数和关键字参数两种,函数调用中写了参数名的就是关键字参数,没有写参数名的就是位置参数,如multiply(4,b=7)中4就是位置参数,b=7就是关键字参数。Python中所有位置参数可以形成一个列表,所有关键字参数可以构成一个字典,所以不管函数的参数是什么都可以归结为两个参数,一个列表和一个字典。可以定义一个包装函数以目标函数fun为参数,在这个函数里面取得相关信息输出之后,再调用目标函数fun。这个包装函数就是函数修饰器。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

【程序代码】j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

输出函数调用信息j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

【代码分析】j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

①:定义函数funinfo(fun)用来产生并返回函数fun的包装器函数wrapper。函数名funinfo就是函数装饰器的名称。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

②:定义函数wrapper(*args,**kargs)用于包装函数fun。参数*args表示用形参中的所有位置参数构成一个列表,列表名为args。**kargs表示用形参中的所有关键字参数构成一个字典,字典名为kargs。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

③:将所有位置参数追加到列表alist后面。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

④:将所有关键字参数追加到列表alist后面。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

⑤:调用目标函数fun,将返回值保存到变量r。这是包装器函数必须要完成的工作,不然就与目标函数没有关系了。如果需要对参数进行一些前置处理就可以放到调用目标函数以前,如本例中的获取参数信息。如果要对函数进行一些善后处理,如检查返回值的范围,就可以在调用后进行。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

⑥:包装器函数wrapper将目标函数的返回值r返回给调用者。返回的值可以是目标函数返回的值,也可以是处理之后的值,这由程序设计需要决定。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

⑦⑧:将目标函数的__name__属性和__doc__属性复制到包装函数wrapper,这样包装函数wrapper就完全变成了目标函数fun。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

⑨:返回包装器函数作为目标函数fun的替代品。以后对目标函数fun的调用其实会变成对包装器函数的调用。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

⑩:对函数fun应用函数修饰器funinfo。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

输出函数调用信息j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

调用funinfo(multiply)后,它会返回包装器函数wrapper,并赋值给变量multiply,而函数multiply的“真身”也会存放到包装器wrapper中,以后对函数multiply的调用就变成了对wrapper的调用,而wrapper函数会在调用函数返回结果之前输出函数的调用信息。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

【优化提升】j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

在上例中使用了wrapper.__name__=fun.__name__和wrapper.__doc__=fun.__doc__来保存目标函数fun的部分信息,在内置模块functools中提供了一个函数修饰器wraps用来保存更多目标函数的信息。修改之后的代码如下:j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

使用了functools修饰后,我们可以从包装器函数wrapper中获得更多关于目标函数fun的信息。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

【技术全貌】j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

除了提供wraps函数修饰器外,functools模块还提供了很多有用的功能帮助我们高效使用函数,部分函数见表5-3-2。j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

表5-3-2 functools模块函数j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

输出函数调用信息j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

续表j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

输出函数调用信息j3r100150满分答卷(100150.com)-青少年编程等级考试及竞赛题库

关 键 词

相关教程

提示声明

  • 免责声明:本站资源均来自网络或者用户投稿,仅供用于学习和交流:如有侵权联系删除!

猜你喜欢