Python中的装饰器 - 扩展篇

基础篇详见:https://blog.youkuaiyun.com/matlab2007/article/details/102896249

(1)带有参数的装饰器
现在函数f中计算a和b的和,然后通过装饰器来统计运行时间,初学者的代码可能如下:

#带有参数的装饰器
def run_time(f):
    def wrapper():
        start_time = time.time()    
        f(a,b)
        end_time = time.time()
        print('程序运行时间为:%s' %(end_time-start_time))
    return wrapper

@run_time
def f(a,b):
    print('开始计算:')
    time.sleep(1)
    print('计算结果%d' %(a+b))
    
f(5,6)

程序运行提示:
TypeError: wrapper() takes 0 positional arguments but 2 were given

正确代码:

def run_time(f):
    def wrapper(a,b):
        start_time = time.time()    
        f(a,b)
        end_time = time.time()
        print('程序运行时间为:%s' %(end_time-start_time))
    return wrapper

@run_time
def f(a,b):
    print('开始计算:')
    time.sleep(1)
    print('计算结果%d' %(a+b))
    
f(5,6)

即内函数wrappe形参如果需要指定的话,则形参的个数必须和被装饰函数f(a,b)的参数个数一致。

(2)无固定参数的装饰器
被装饰的函数其形参个数可能各异,而装饰器将来可能装饰多个函数,所以考虑到装饰器的通用性,装饰器函数的形参往往定义为可变参数。

def run_time(f):
    def wrapper(*args,**kwargs):
        start_time = time.time()    
        f(*args,**kwargs)
        end_time = time.time()
        print('程序运行时间为:%s' %(end_time-start_time))
    return wrapper

@run_time
def f(a,b):
    print('开始计算:')
    time.sleep(1)
    print('计算结果%d' %(a+b))

@run_time
def f2(a,b,c):
    print('开始计算:')
    time.sleep(1)
    print('计算结果%d' %(a+b+c))
    
f2(5,6,7)
f(5,6)

(3)使用多个装饰器,装饰一个函数

def run_time(f):
    def wrapper(*args,**kwargs):
        start_time = time.time()    
        f(*args,**kwargs)
        end_time = time.time()
        print('第一个装饰器')
        print('程序运行时间为:%s' %(end_time-start_time))
    return wrapper
    
def run_hello(f):
    def wrapper(*args,**kwargs):
        f(*args,**kwargs)
        print('第二个装饰器,只打印一句话')
    return wrapper    

@run_hello
@run_time
def f(a,b):
    print('开始计算:')
    time.sleep(1)
    print('计算结果%d' %(a+b))
    
f(5,6)

运行结果:

开始计算:
计算结果11
第一个装饰器
程序运行时间为:0.9999358654022217
第二个装饰器,只打印一句话

(4)有函数返回值的装饰器

#带有参数的装饰器
def run_time(f):
    def wrapper(*args,**kwargs):
        start_time = time.time()    
        w = f(*args,**kwargs)
        end_time = time.time()
        print('程序运行时间为:%s' %(end_time-start_time))
        return w
    return wrapper
 

@run_time
def f(a,b):
    return a+b
    
f(5,6)

如果被装饰的函数有返回值,则wrapper函数内可以用临时变量接受该返回值,打印或作为wrapper函数的返回值均可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值