python函数装饰器

什么是装饰器?

在不修改原函数及其调用方式的情况下对原函数的功能进行扩展。

装饰器的本质是什么?

一个闭包函数

我们来复习一下之前的知识。

def outter():
    def inner():
        print("我是里层")
    print("我是外层")
outter()

"""
运行结果:

我是外层
"""

总结:我们可以看到调用这个outer()方法,只执行了外层函数中的内容,却没有执行内嵌函数中的内容,这是因为没有调用内嵌函数。

def outter():
    def inner():
        print("我是里层")
    print("我是外层")
    inner()
outter()

'''
运行结果:

我是外层
我是里层

'''

总结:根据前两段代码,我可以总结,函数不调用,不执行。

大家还记得闭包吗?如果不记得了下面python闭包,复习一下闭包的知识。
python闭包

通过一般方法扩展功能

具备了上面的知识我们就可以通过一般方法扩展功能

def outter(f):
    def inner():
        print("我是里层")
        f()
    return inner

def func():
    print("我是扩展功能的函数")

outter(func)()

'''
运行结果:

我是里层
我是扩展功能的函数
'''

总结:这其实完成了装饰器的作用,在不改变原函数的调用方式,提高函数的功能。

使用装饰器扩展功能

语法糖
格式:@装饰器名称
在闭包的基础上,及上面的代码,通过使用装饰器完成装饰。
代码示例

def outter(f):
    def inner():
        print("我是里层")
        f()
    return inner

@outter

def func():
    print("我是扩展功能的函数")
func()

'''
运行结果:

我是里层
我是扩展功能的函数
'''

定义一个带参数的装饰器

代码示例

def outter(f):
    def inner(s):
        print("我是里层")
        f(s)
    return inner

@outter

def func(s):
    print("我是扩展功能的函数",s)
func("我是从扩展中传进去的参数")

'''
运行结果:

我是里层
我是扩展功能的函数 我是从扩展中传进去的参数
'''

定义一个带任意参数的装饰器

代码示例

def outter(f):
    def inner(*args,**kwargs):
        print("我是里层")
        f(*args,**kwargs)
    return inner

@outter

def func(*args,**kwargs):
    print("我是扩展功能的函数",args,kwargs)
func("元组参数1","元组参数2",字典健1="值1",字典健2="值2")

'''
运行结果:

我是里层
我是扩展功能的函数 ('元组参数1', '元组参数2') {'字典健1': '值1', '字典健2': '值2'}
'''

使用@wraps()进行查看被装饰函数的信息

需要导入包from functools import wraps
代码示例:

from functools import wraps
def outter(f):
    @wraps(f)
    def inner(*args,**kwargs):
        print("我是里层")
        f(*args,**kwargs)
    return inner

@outter

def func(*args,**kwargs):
    '''
    :param args:位置参数
    :param kwargs: 关键词参数
    :return: 无返回值
    '''
    print("我是扩展功能的函数",args,kwargs)
func("元组参数1","元组参数2",字典健1="值1",字典健2="值2")
print(func.__doc__)
print(func.__name__)

'''
运行结果:

我是里层
我是扩展功能的函数 ('元组参数1', '元组参数2') {'字典健1': '值1', '字典健2': '值2'}

    :param args:位置参数
    :param kwargs: 关键词参数
    :return: 无返回值
    
func
'''

总结:__name__的意思是查看传给形参f的参数是什么。
__doc__查看函数的描述信息

一个函数定义多个装饰器

执行顺序是从里到外,最先调用的是最里层的装饰器,最后调用最外层的装饰器

def outter1(f):
    def inner1():
        print("执行outter1的f before")
        f()  
        print("执行outter1的f after")
    return inner1

def outter2(f):
    def inner2():
        print("执行outter2的f before")
        f()
        print("执行outter2的f after")
    return inner2

@outter1 #inner1=outter1(inner2)
@outter2 #func=outter2(func)

def func():
    print("我是扩展功能的函数")

func()

'''
运行结果:

执行outter1的f before
执行outter2的f before
我是扩展功能的函数
执行outter2的f after
执行outter1的f after
'''

分析:outter1中的f其实是inner2的内存地址,所以执行完print(“执行outter1的f before”)后,会进入到inner2函数中去,执行print(“执行outter2的f before”),这时outter2函数中的f,才是func()函数的内存地址,所以打印了print(“我是扩展功能的函数”),再执行print(“执行outter2的f after”),inner2函数中的东西执行完,回到inner1中去执行print(“执行outter1的f after”)。程序结束。
总结
比如

@x
@y
def f():
	pass

执行顺序是从里到外,最先调用最里层的装饰器,最后调用最外层的装饰器,它等效于如下

f=x(y(f))

来一波,推送吧!
群号:781121386
群名:人生苦短,我学编程
欢迎大家加入我们,一起交流技术!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值