装饰器



"""
def deposit():
    print("存款中....")
def withDrawal():
    print("取款中...")
以上两个函数不能修改
可以在不改变原函数以及原函数的调用的情况下扩展原函数的功能呢?
当然是有的,这就是python中的装饰器。
"""
def check_pwd(func):
    def inner():
        print("密码验证中....")
        func()
    return inner
@check_pwd #相当于deposit = check_pwd(deposit)
def deposit():
    print("存款中....")
@check_pwd  #相当于withDrawal = check_pwd(withDrawal)
def withDrawal():
    print("取款中...")


button = 2
if button==1:
    deposit()
else:
    withDrawal()
带参数
ef celebrator(func):
    def inner(*args,**kwargs):
        print("新增功能")
        func(*args,**kwargs)
    return inner
@celebrator
def myprint(a):
    return a
@celebrator
def hisprint(b):
    print(b)
myprint("Python社区")

ret1 = myprint("huowu")
ret2 = hisprint([1,2,3])
print("返回结果{},{}".format(ret1,ret2))

输出:
新增功能
新增功能
新增功能
[1, 2, 3]
返回结果None,None

可以看到,无论被装饰的函数有无返回值,其结果都无返回值,原因其实很简单,因为inner()函数根本就没有返回值。为了实现有返回值的函数被装饰之后仍然有返回值,需要inner函数与被装饰函数的返回值保持一致。

def celebrator(func):
    def inner(*args,**kwargs):
        print("新增功能")
        ret = func(*args,**kwargs)
        return ret
    return inner
@celebrator
def myprint(a):
    return a
@celebrator
def hisprint(b):
    print(b)
myprint("Python社区")

ret1 = myprint("huowu")
ret2 = hisprint([1,2,3])
print("返回结果{},{}".format(ret1,ret2))

在这里插入图片描述
可以看到,有返回值的函数被装饰之后依然有返回值,没有返回值的函数被装饰之后则没有返回值,符合我们想要的结果。

def celebrator(func):
    def inner(*args,**kwargs):
        print("="*15)
        ret = func(*args,**kwargs)
        return ret
    return inner
def celebrator2(func):
    def inner(*args,**kwargs):
        print("*"*15)
        ret = func(*args,**kwargs)
        return ret
    return inner

@celebrator
@celebrator2
def myprint():
    print("Hello")
myprint()

输出:
===============
***************
Hello

等价于

def get(chars):
    def myprints(func):
        def inner():
            print(chars*15)
            func()
        return inner
    return myprints
@get("=")
@get("*")
def myprint():
    print("Hello")
myprint()
执行顺序
  • 在函数定义阶段:执行顺序是从最靠近函数的装饰器开始,自内而外的执行
  • 在函数执行阶段:执行顺序由外而内,一层层执行
def war1(func):
    print("war1")
    def inner(*args, **kwargs):
        print("======war1 start=====")
        func(*args, **kwargs)    #inner
        print("======war1 end=====")
    return inner

def war2(func):
    print("war2")

    def inner(*args, **kwargs):
        print("======war2 start=====")
        func(*args, **kwargs)
        print("======war2 end=====")

    return inner


@war1
@war2
def f():
    print("****self****")

没有函数执行,只留下函数的定义,装饰器函数也执行了,输出:
war2
war1

此处我们需要先弄清楚,函数和函数调用的区别,f 是一个函数,它的值是函数本身, f( )是函数的调用,它的值是函数的执行结果

在被装饰函数定义阶段,也就是函数调用之前:

@war1
@war2
def f():
    print("****self****")

这段代码等价于:

war1(war2(f))

war1和war2的返回值都是一个函数,所以war1(war2(f))也是一个函数,war2包含了f函数,war1包含了war2

f() 相当于 war1(war2(f))()

所以f ( )在执行时,war2–>war1–> war1–>war2–>f -->war2–>war1 按照这样的顺序执行
在这里插入图片描述
在这里插入图片描述
参考:https://blog.csdn.net/u013411246/article/details/80571462

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值