python之装饰器

引言

软件开发中,当需要创建高度重复的代码时,需要寻求一种优雅的解决方案。python中的元编程即解决这类问题,通过创建函数和类来修改、生成或包装已有的代码。装饰器就是python中用来包装函数的一种机制。

内建装饰器

python提供了一些内建装饰器,比如我们常用的@staticmethod、@classmethod、@property。

  • 装饰器内部的代码一般会涉及创建一个新的函数,利用*args,**kwargs接收任意参数,在该函数内部会调用被包装的函数,并返回被包装函数的结果;最后这个新创建的函数作为装饰器的结果返回。
  • 需要注意的一点,装饰器通常不会修改被包装函数的返回结果。

自定义装饰器

例1:统计函数执行时间
import time
from functools import wraps

# 定义装饰器函数:统计函数执行时间
def timethis(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(func.__name__, end-start)
        return result
    return wrapper

# 使用装饰器
@timethis
def count(n):
    while n > 0:
        n -= 1
        print(n)

if __name__ == '__main__':
    count(5)

结果输出如下:

4
3
2
1
0
count 0.0

例2:记录日志
import time
from functools import wraps

# 定义装饰器函数:日志记录
def logthis(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(func.__name__, 'start run..................')
        result = func(*args, **kwargs)
        print(func.__name__, 'finished!!!!!!!!!!!!!!!!!!!')
        return result
    return wrapper

# 使用装饰器
@logthis
def count(n):
    while n > 0:
        n -= 1
        print(n)

if __name__ == '__main__':
    count(5)

结果输出如下:

count start run…
4
3
2
1
0
count finished!!!

例3:使用多个装饰器

如果我们对一个函数同时使用两个装饰器,会发生什么呢?还是用例1和例2中定义的装饰器,

# 使用装饰器
@logthis
@timethis
def count(n):
    while n > 0:
        n -= 1
        print(n)

if __name__ == '__main__':
    count(5)

结果输出如下:

count start run…
4
3
2
1
0
count 0.0
count finished!!!

如果我们在使用装饰器时,调换下装饰器的顺序,结果会有不同。

# 使用装饰器,此处调换装饰器的顺序
@timethis
@logthis
def count(n):
    while n > 0:
        n -= 1
        print(n)

if __name__ == '__main__':
    count(5)

输出结果如下:

count start run…
4
3
2
1
0
count finished!!!
count 0.0

可以看出,timethis装饰器的输出内容在最外面。可以理解为,装饰器是可以多层嵌套使用的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值