python编写装饰器_十分钟搞定python装饰器

我们在做python编程的时候,经常会遇到函数定义的时候,最上面一行有@符号的语句,这叫做装饰器。

装饰器,英文名为Decorators,用一句话来简单说一下就是:在不改变当前函数的逻辑基础上,赋予当前函数更多的能力。

知识点1:函数也是对象,可以作为参数

函数也是对象,也就是我们可以直接使用函数作为参数,传入到另一个函数。

def hi(name='Andy'):

print(f'hello,{name}!')

def printf(fn):

print(fn)

printf(hi)

运行结果:

知识点2:函数中也可以定义函数,同时返回函数

在函数中定义另和函数,另一个函数是可以作为对象直接返回。

def hi(name='Andy'):

print(f'hello,{name}!')

def printf(fn):

def wrapper():

print(fn)

return wrapper

printf(hi)()

运行结果:

知识点3:函数中调用【作为参数的函数】

def hi(name='Andy'):

print(f'hello,{name}!')

def printf(fn):

def wrapper(*args, **kwargs):

print('这里是fn的前置逻辑')

fn(*args, **kwargs)

print('这里是fn的后置逻辑')

return wrapper

printf(hi)(name='ruby')小提示:*args是指python函数的参数没有给定初始值的参数。*kwargs是指我们给定初始值的参数。我们可以使用*args, **kwargs,直接将一个函数的参数,传给另一个函数。

运行结果:

知识点4:函数中调用【作为参数的函数】,并返回结果

def hi(name='Andy'):

return f'hello,{name}!'

def printf(fn):

def wrapper(*args, **kwargs):

print('这里是fn的前置逻辑')

ret = fn(*args, **kwargs)

print('这里是fn的后置逻辑')

return ret

return wrapper

result = printf(hi)(name='ruby')

print(result)

运行结果:

到底什么是装饰器

讲了4个知识点终于到了核心部分,其实在知识点4中,我们已经了掌握了装饰器,只需要稍加改变就变成了一个我们想要看到的@符号装饰的代码装饰器就是对函数进行包裹后的函数,目的就是在包裹函数中处理额外的逻辑

def printf(fn):

def wrapper(*args, **kwargs):

print('这里是fn的前置逻辑')

ret = fn(*args, **kwargs)

print('这里是fn的后置逻辑')

return ret

return wrapper

@printf

def hi(name='Andy'):

return f'hello,{name}!'

result = hi(name='ruby')

print(result)

运行结果:

运行的结果是不是与知识点4的代码相同,同时我们调用的方式,做了简单,也就是我们直接调用我们的函数就可以了。

扩展:一道关于装饰器的面试题:请设计一个装饰器,他可以作用到任何函数上,并打该函数的的执行时间。

(1)定义一个函数

def hi(name='Andy'):

print(f'hello,{name}!')小提示:f开头表示在字符串内支持大括号内的python 表达式

(2)编写装饰器函数

import time, functools

def excute(fn):

@functools.wraps(fn)

def wrapper(*args, **kwargs):

startTime = time.time()

result = fn(*args, **kwargs)

endTime = time.time()

print(f'Function{fn.__name__}excute start: {endTime-startTime}')

return result

return wrapper小提示:@functools.wraps(fn),用来将wapper的函数相关的内置变量名,比如__name__与原有的函数保持一致。

(3)完整代码如下

import time, functools

def excute(fn):

@functools.wraps(fn)

def wrapper(*args, **kwargs):

startTime = time.time()

result = fn(*args, **kwargs)

endTime = time.time()

print(f'Function{fn.__name__}excute start: {endTime-startTime}')

return result

return wrapper

@excute

def hi(name='Andy'):

print(f'hello,{name}!')

hi(name='Ruby')

执行结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值