【python之十万个为什么】装饰器函数形参为什么是被装饰的函数

系列文章目录
 

【python之十万个为什么】闭包为什么需要return内层函数


前言

        装饰器是python新人比较难以理解的部分。它对格式有较高的要求,比如说,装饰器函数的形参要求是被装饰函数.例如:def decorator(function)#decorator是装饰器,function既是形参,又是被装饰函数。这样严格的要求有什么意义呢?从实际测试结果看,如果不这样,装饰器就会陷入无限死循环状态。


一、装饰器函数形参为什么是被装饰的函数

首先放入一段正确的代码:

#新装饰器测试—无限循环
def decorator(func):
    def wrapper():
        func()
        
    return wrapper

@decorator
def func():
    print('这是一段正确代码')
   

func()

这段代码运行结果流畅无误。但如果我们测试,把decorator(func)的形参改个名字呢?

def decorator(function):
    def wrapper():
        func()
        
    return wrapper

@decorator
def func():
    print('我为什么错')
   

func()

 这段代码会出现无限死循环,也就是递归错误。出现这种的原因是什么呢?我们通过代码比较进行分析。

#这是正确代码
def decorator(func):#3
    def wrapper():
        func()#4
    return wrapper

@decorator
def func():#2
    print('这是正确代码')

func()#1

 正常运行的装饰器中,func函数的传递过程如下:

        1.func#1被调用;

        2.func()#2开始运行,运行逻辑是decorator(func);

        3.上一步中的decorator(func)会根据decorator(func):#3的定义进行下一步操作,等同于启用了一个新函数decorator(func),这个函数的作用是运行wrapper()函数;

   4.请注意,这里的func()#4要两部分考虑,它的代码复制func():#2,但逻辑却来自decorator(func):#3。也就是说,func():#2和(func):#3虽然代码一摸一样,但却是两个函数

#这是错误代码
def decorator(function):#3
    def wrapper():
        func()#4
    return wrapper

@decorator
def func():#2
    print('这是错误代码')

func()#1

而在这段错误代码中,因为形参是function,破坏了装饰器的格式。所以func():#2就作为decorator(function)的实参,但仅此而已,后面步骤的内层函数激活和func():#2一点关系都没有。此外,此时的func()#4和func():#2一摸一样,就是一个函数。调用func()#4就是调用func():#2,所以,内层函数会激活func():#2,反过来func():#2会再次作为decorator(function)的实参激活装饰器函数,装饰器函数再调用内层函数并再次激活unc():#2,最终陷入无限循坏的bug中。

总结

简单来说,装饰器函数形参必须是被装饰的函数。只有这样,被装饰函数才能从装饰器中调用。否则,装饰器函数仅仅是激活了内层函数,并没有起到调用被装饰函数的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值