python装饰器设置参数方式
前言
一开始没打算写这篇文章的,今天整理笔记看到了偏函数的帖子在拿装饰器举例对比。
然后就想到既然装饰器本身也是函数,为啥不可以给装饰器也设置上参数,来进一步提高装饰器的复用性呢?
于是把思路整理了一下,就有了本文。
装饰器原理回顾
在我的另一篇关于装饰器的文章中有跟大家提到过,装饰器实际上就是一个闭包函数,在闭包函数的内部函数中添加装饰的内容并调用被装饰的函数。
以达到 fun = decorator(fun) 的效果:
def decorator(fun): def inner(name): print("Hi") fun(name) return inner @decorator def get_last_name(name): print(f"你就是小{name[0]}吧") get_last_name("王富贵")
从上面的例子中我们可以简单的总结出装饰器不同参数设置的规律:
装饰器外部的函数传的参数是被装饰函数的函数名,内部函数的参数是被装饰函数的参数。
使用装饰器时,被装饰函数的参数name是先传递给装饰器的内部函数,内部函数调用被装饰函数时将参数name传递给被装饰函数。
而外部函数接收的参数时被装饰函数的函数名,注意,外部函数的参数只能有一个也只能是被装饰函数的函数名。
"""错误写法""" def decorator(fun,*args_outer): def inner(*args_inner): pass
一个很简单的道理,装饰器的用法是@+装饰器名+被装饰函数。
其工作原理就是fun = decorator(fun) ,即装饰器接收的第一个参数就必须是被装饰函数名,如果设置其他参数的话在第一个参数都缺失的情况下怎么传?
不过并不是完全没办法,换一换思路就可以了,下面就是本文要讲的干货了
装饰器设置参数:多层闭包嵌套
我们都知道,装饰器就是一个闭包函数,外部接收被装饰函数名,内部装饰再调用被装饰函数。
那么我们为啥不在这个闭包函数的外部再嵌套一层函数用来接收自己想要的参数呢?
废话不多说,举例子上代码:
"""假设一家烧烤店可以送外卖,外卖比堂食要多出打包盒跟配送费两项费用""" def decorator_outer(*args_outer): # 接收正常在店内消费之外的其他费用 def decorator_inner(fun): def inner(*args_inner): # 接收在正常参数的费用 new_args = args_outer + args_inner return fun(*new_args) return inner return decorator_inner @decorator_outer(3,5) # 打包盒3元,配送费5元 def monetary(*args): # 计算每份菜品价格之和 themoney = 0 for m in args: themoney += m return themoney
上一次的文章说到,闭包调用内部函数的方法是decorator()(),那么类似上述代码中多嵌套了一层就自然是decorator_outer()()()。
也就是说按照装饰器的工作原理,上述代码的工作原理就是
monetary = decorator_outer(3,5)(monetary)
小小的提醒一下,闭包嵌套层次越多就一定要注意看看被装饰函数的返回值有没有被一层层的返回出来,不然最后返回一个空值又不报错很难排查。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
matplotlib之Font family [‘sans-serif‘] not&nbs
本文主要介绍了matplotlib之Font family [‘sans-serif‘] not found的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2023-03-03Python2.6版本中实现字典推导 PEP 274(Dict Comprehensions)
这篇文章主要介绍了Python2.6版本中实现字典推导 PEP 274(Dict Comprehensions),本文给出了表达式写法和for循环写法两种方法实现字符推导,需要的朋友可以参考下2015-04-04pytorch中的named_parameters()和parameters()
这篇文章主要介绍了pytorch中的named_parameters()和parameters()使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-09-09在Python的Flask中使用WTForms表单框架的基础教程
WTForms由Python写成,为表单而生,提供了很多制作Web表单的实用API,和Flask框架结合使用效果拔群,这里我们就一起看一下在Python的Flask中使用WTForms表单框架的基础教程2016-06-06Windows下Python的Django框架环境部署及应用编写入门
这篇文章主要介绍了Windows下Python的Django框架环境部署及程序编写入门,Django在Python的框架中算是一个重量级的MVC框架,本文将从程序部署开始讲到hellow world web应用的编写,需要的朋友可以参考下2016-03-03
最新评论