python 装饰器

一、含义

首先,装饰器是用来给目标函数“装饰”用的;其次,装饰器是一个函数,它返回的是一个装饰好的目标函数

二、举例

step1:

比如,我们写了一个求平方的目标函数:

def my_pow(x):
    # 求平方
    print(x ** 2)

为了提示函数确实执行了,改为:

def my_pow(x):
    # 求平方
    print('starting my_pow...')
    print( x ** 2)

如果要将很多函数都加上这个提示功能,则需要重复大量代码,于是将核心代码包装在另外一个函数add_warning中:

def add_warning(func, x):
    print('starting %s...' % func.__name__)
    func(x)

def my_pow(x):
    # 求平方
    print(x ** 2)

# 36
add_warning(my_pow, 6)

但这种方式很绕,明明想要执行my_pow,却要去执行add_warning,并且传参也不太方便。

step2:

于是,利用可变参数和关键字参数,再改一下:

def add_warning(func):
    def wrapper(*args, **kwargs):
        print('starting %s...' % func.__name__)
        return func(*args, **kwargs)
    return wrapper

def my_pow(x):
    # 求平方
    print(x ** 2)

my_pow = add_warning(my_pow)

# 36
my_pow(6)

上面的代码中,add_warning就是一个装饰器,它是一个函数,把计算平方的核心代码包裹在wrapper函数中,然后装饰器把wrapper函数返回就可以了。

step3:

再进一步,为了不傻逼一样地将装饰器add_warning在代码中显式地赋给my_pow函数,于是高大上地改为如下这种形式:

def add_warning(func):
    def wrapper(*args, **kwargs):
        print('starting %s...' % func.__name__)
        return func(*args, **kwargs)
    return wrapper

@add_warning
def my_pow(x):
    # 求平方
    print(x ** 2)

# 36
my_pow(6)

这样,赋值操作就交给python解释器去完成了。

3、question

你可能会问,为什么不将step2中wrapper函数去掉,直接改为:

def add_warning(func, *args, **kwargs):
    print('starting %s...' % func.__name__)
    return func(*args, **kwargs)

def my_pow(x):
    # 求平方
    print(x ** 2)

my_pow = add_warning(my_pow)

# 36
my_pow(6)

因为,此时执行add_warning(my_pow)后,返回的并不是一个装饰好的函数,而是func执行后的具体值(结果),这与我们的目标不符。当然上面这段代码也会报错。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值