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)

结果显示:

总结:要弄清楚;加上装饰器之后;同样调用之前的函数;是在执行那个函数;这样才能知道那个函数接收参数;才能保证即增加功能又能保证原函数功能的完整

 

我们知道程序中只要加上装饰器;则装饰器后面紧跟着的函数;执行的时候都会被修改。上面我们讲到可以传入参数。

问题:如果后面跟着多个函数;而且每个函数接收的参数不一样,那怎么处理? 

思路:得谁让装饰器内部函数接收认任意个数得参数;有没办法那?
之前我们学习函数得时候;对函数接收参数得个数讲解中;有个接收任意个数得参数
写法:
1、*args-->在形参前面加 * ;表示接收任意个数得参数;如f1(1, 2, 3)-->这个形参是个元组
2、**kwargs-->可以接收字典类型得参数;如:f1(k1 = 123)
3、两个合起来;*args, **kwargs:就是万能参数
# 定义的装饰器函数
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)

注意:传入参数的时候;原函数参数个数有多少个,则执行函数的时候也要传多少个。

 

问题:我们先使用装饰器为所有的方法添加了功能;但是此时我们又想再添加功能;但是不是之前添加功能的所有方法;而是我只需要在某几个方法上再增加一些功能?

1、写2个装饰器;(每个方法前面引用一个装饰器)
  • 一个包含增加一个功能
  • 一个包含增加2个功能
操作步骤:将装饰器分别写在不同需求的方法的前面(@开头)
 
2、写2个装饰器:(根据需求的不同;每个方法上面至少一个装饰器)
  • 一个包含所有方法都要求增加的功能
  • 一个只包含部分方法要求增加的功能
操作步骤:
  • 将包含所有方法都要求增加功能的装饰器写在全部的方法上面(@开头)
  • 再将只包含部分方法要求功能的装饰写在;对应的方法上面;注意要写在 所有方法都需求功能的装饰器 之上 

意思:就是写两个装饰器

总结:
1、从前面的内容即分析上我们得出:一个函数方法可以拥有多个装饰器
2、理解执行顺序;又上往下;@outer_1执行的是ouetr_2的结果当作参数传入后执行
@outer_1
@outer_2
def fun(a1, a2):
    return a1 + a2
个人理解:执行是由上往下的;但是结果确实又下往上返回的。
意思:先执行outer_2然后将内部函数当作参数传入outer_1中;然后计算出结果

 

装饰器的应用:

1、比如你去某商城;如果你没登陆;而点我的订单等之类的操作;都会跳到登陆页面让你先登陆;这里就使用了装饰器 

2、有些页面分不同等级的会员显示的结果就不一样;就用了多个装饰器

posted on 2016-10-19 00:05  jayafs  阅读(78)  评论(0)    收藏  举报

导航