python学习 day8
装饰器(二)
只要函数应用装饰器,那么函数就会被重新定义,定义为装饰器的内层函数。
装饰器添加参数
# 定义的装饰器函数 def outer(arg): def inner(a1, a2): print("我是函数执行前增加的内容") r = arg(a1, a2) print("我是函数执行后增加的内容") return r return inner # 函数之前没加装饰器 def fun(a1, a2): return a1 + a2 ret = fun(1, 2) print(ret) # 结果 3
带参数函数加上装饰器:
# 定义的装饰器函数 def outer(arg): def inner(a1, a2): print("我是函数执行前增加的内容") r = arg(a1, a2) print("我是函数执行后增加的内容") return r return inner @outer # 加上装饰器 def fun(a1, a2): return a1 + a2 ret = fun(1, 2) print(ret)
结果显示:

总结:要弄清楚;加上装饰器之后;同样调用之前的函数;是在执行那个函数;这样才能知道那个函数接收参数;才能保证即增加功能又能保证原函数功能的完整
我们知道程序中只要加上装饰器;则装饰器后面紧跟着的函数;执行的时候都会被修改。上面我们讲到可以传入参数。
问题:如果后面跟着多个函数;而且每个函数接收的参数不一样,那怎么处理?
# 定义的装饰器函数 def outer(arg): def inner(*args, **kwargs): print("我是函数执行前增加的内容") r = arg(a1, a2) print("我是函数执行后增加的内容") return r return inner @outer # 加上装饰器 def fun(a1, a2): return a1 + a2 ret = fun(1, 2) print(ret)
这样确实能改变装饰器接收参数个数不统一的问题。
问题:但是,我们知道*args接收的是个元组;**kwargs接收的字典;那我们接收了参数要传到原函数(上面的列子调用的原函数:r = arg(a1, a2))执行;按思路来说我们的去*args或者**kwargs中去找出我们的参数然后再按着顺序的将参数传入装饰器中调用的原函数(上面的列子调用的原函数:r = arg(a1, a2))
装饰器运用参数传递示意图:

但是:幸运的是,python并比希望我们这样做;它内部已经做了优化的。
所以;只要我们在写装饰器的时候按下面这样写;不管你用于什么样的函数;传什么样的参数;都可以接受使用。
# 定义的装饰器函数 def outer(arg): def inner(*args, **kwargs): print("我是函数执行前增加的内容") r = arg(*args, **kwargs) print("我是函数执行后增加的内容") return r return inner @outer # 加上装饰器 def fun(a1, a2): return a1 + a2 ret = fun(1, 2) print(ret)
注意:传入参数的时候;原函数参数个数有多少个,则执行函数的时候也要传多少个。
问题:我们先使用装饰器为所有的方法添加了功能;但是此时我们又想再添加功能;但是不是之前添加功能的所有方法;而是我只需要在某几个方法上再增加一些功能?
- 一个包含增加一个功能
- 一个包含增加2个功能
- 一个包含所有方法都要求增加的功能
- 一个只包含部分方法要求增加的功能
- 将包含所有方法都要求增加功能的装饰器写在全部的方法上面(@开头)
- 再将只包含部分方法要求功能的装饰写在;对应的方法上面;注意要写在 所有方法都需求功能的装饰器 之上
意思:就是写两个装饰器
@outer_1 @outer_2 def fun(a1, a2): return a1 + a2
装饰器的应用:
1、比如你去某商城;如果你没登陆;而点我的订单等之类的操作;都会跳到登陆页面让你先登陆;这里就使用了装饰器
2、有些页面分不同等级的会员显示的结果就不一样;就用了多个装饰器
浙公网安备 33010602011771号