Python装饰器

一、装饰器的定义:

就是在不修改原有函数代码的前提下,给已有函数增加额外功能的函数,它本质上就是一个闭包函数

Python中有自带的装饰器:@staticmethod

二、装饰器的功能特点:

  1. 不修改已有函数的源代码
  2. 不修改已有函数的调用方式
  3. 给已有函数增加额外的功能

三、实例

1、无参函数

假设我们有一个登陆函数,若我们想修改该函数,即增加一个验证登录的功能。此时我们可以直接修改原函数的代码,但是在实际生产开发中不合理,相比之下我们更会选择使用装饰器:
在这里插入图片描述
在这里插入图片描述

本质就是一个闭包函数原理:

1、在函数嵌套(函数里面再定义函数)的前提下
2、内部函数使用了外部函数的变量(还包括外部函数的参数)
3、外部函数返回了内部函数
在这里插入图片描述
代码中传入的func参数是上面的登录函数,然后我们在登录函数前增加一个验证登录的功能。

在这里插入图片描述
注意: 闭包函数写完之后,只需要在原登录函数的开头加一个:@func_out便可增加新的功能。当我们运行程序时,添加装饰器那行代码会先执行,当使用装饰器时(“@func_out”)相当于计算机默认执行了:login=func_out(login)

最后重新调用login()函数便可使用增加了新功能的函数了。

结论:
1、调用login()相当于==>func_in(), 调用被装饰的函数就相当于调用闭包中的内层函数
2、外层函数的参数 func ==> 原始的login

2、有参函数

在这里插入图片描述
运行结果:
在这里插入图片描述

结论:
1、调用my_test()相当于==>func_in(), 调用被装饰的函数就相当于调用闭包中的内层函数
2、外层函数的参数 func ==> 原始的my_test

3、带返回值的函数

在这里插入图片描述

结果分析: func()有没有返回值跟func_in 没有关系,默认返回None。
所以当调用my_test()时候相当于调用func_in(),而func_in()是没有返回值的,默认返回None.

解决办法:就是将func_in()函数中的func()用一个变量来接收,然后将这个变量通过return来返回.
在这里插入图片描述

4、通用版本装饰器

def func_out(func):
    #函数中如果没有return 证明函数是没有返回值的
    def func_in(*args,**kwargs):
        ret = func(*args,**kwargs)
        return ret
    return func_in

@func_out
def my_test(*args,**kwargs):
    return 100

a = my_test()
print(a)

5、多个装饰器

def func_out01(func01):
    print("this is func_out01")
    def func_in01():
        print("this is func_in01")
        func01()
    return func_in01
def func_out02(func02):
    print("this is func_out02")
    def func_in02():
        print("this is func_in02")
        func02()
    return func_in02
#就近原则,谁距离被装饰函数近,谁先被执行
@func_out01
@func_out02
def my_test():
    print("my_test")

my_test()

运行结果:
在这里插入图片描述

结果分析:

当运行程序后是从上往下执行的,先执行 @func_out01,但是因为装饰器只能装饰函数,装饰器是装饰不了函数的。
于是执行下一行代码:@func_out02,执行my_test = func_out02(my_test),即my_test作为函数传入了 func_out02,先显示了“this is func_out02”,然后将func_in02返回了。
即生成了新函数:

@func_out02
def my_test():
    print("my_test")

此时,@func_out01便可执行,同理先显示了“this is func_out01”,然后将func_in01返回了。
在这里插入图片描述

6、带参数的装饰器

(1)定义:
带参数的装饰器只需要在原有不带参的装饰器外再套上一个函数,该最外层函数中可定义参数,嵌套里面的函数可引用该参数。

def my_func(num):# fum = 10
    def func_out(func):
        def func_in(a,b):
            if num == '*':
                print("相乘为:",a*b)
            if num == '+':
                print("相加为:",a+b)
            func(a,b)
        return func_in
    return func_out
@my_func('*')
# 1 my_func
# 2 @func_out
# 3 my_test = func_out(my_test)
def my_test(a,b):
    print(a,b)
#1 my_test()==> func_in()
#2 func() ==>原始的my_test()
my_test(3,4)

运行结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值