python装饰器用法

为什么用装饰器?

  • 第一个原因是,使用装饰器可以提升代码复用,避免重复冗余代码。如果我有多个函数需要测量执行时间,我可以直接将装饰器应用在这些函数上,而不是给多个函数加上一样的代码。这样的代码既元余也不方便后面维护
  • 第二个原因是,使用装饰器可以保证函数的逻辑清晰。如果一个本身功能就很复杂的函数,我还要通过修改内部代码来测量运行时间,这样会模糊函数自身的主逻辑。同时,软件开发的一个原则就是单一职责,也就是说,一个函数只应该承担一项责任
  • 第三,通过装饰器,我们可以扩展别人的函数。想象我们正在使用一个第三方库的函数,但我要添加额外的行为,比如测量运行时间,那我就可以用装饰器去包装,而不是跑到库里面去修改。
import time
import math


#函数接收的参数为函数
def mysqrt(x):
    return math.sqrt(x)

def print_running(f,x):
    print(f'{f.__name__} is running')
    return f(x)

result= print_running(mysqrt,9)
print(result)

mysqrt is running
3.0

#基本的装饰器例子

import time
def myDecorator(func):
    def warpper(*args,**kwargs):
        start_time=time.time()
        result=func(*args,**kwargs)
        end_time=time.time()
        print(f'{func.__name__} running time :{end_time-start_time}')
        return result
    return warpper
    
dec_mysqrt=myDecorator(mysqrt)
result=dec_mysqrt(9)
print(result)

#使用@语法完成函数名字上面代码段的dec_mysqrt=myDecorator(mysqrt)替换
@myDecorator#函数接收的参数为函数
def mysqrt(x):
    return math.sqrt(x)

x=mysqrt(10)
print(x)

mysqrt running time :0.0
3.0

#装饰器生成器:比如要要测量某函数运行时间是否超过阈值,但不同函数的阈值是不一样的,所以需要定义多个装饰器应对不同阈值吗?不,只需要用装饰器生成器
def timer(threshold):
    def decorator(func):
        def warpper(*args,**kwargs):
            start_time=time.time()
            result=func(*args,**kwargs)
            end_time=time.time()
            if (end_time-start_time>threshold):
                print(f'{func.__name__} running time is over {threshold} seconds')
            return result
        return warpper
    return decorator

@timer(0.2)
def sleep_04():
    time.sleep(0.4)

# #上述写法的等价写法
# def sleep_04():
#     time.sleep(0.4)
# sleep_04 =timer(0.2)(sleep_04)

sleep_04()
print(sleep_04.__name__)

sleep_04 running time is over 0.2 seconds
warpper

#但是上面的代码的sleep_04.__name__是warpper,不是sleep_04。
#能继承函数名字等参数的装饰器生成器

import functools
def timer(threshold):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args,**kwargs):
            start_time=time.time()
            result=func(*args,**kwargs)
            end_time=time.time()
            if (end_time-start_time>threshold):
                print(f'{func.__name__} running time is over {threshold} seconds')
            return result
        return wrapper
    return decorator

@timer(0.2)
def sleep_04():
    time.sleep(0.4)
# #上述写法的等价写法
# def sleep_04():
#     time.sleep(0.4)
# sleep_04 =timer(0.2)(sleep_04)

sleep_04()
print(sleep_04.__name__)

sleep_04 running time is over 0.2 seconds
sleep_04

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值