Python functools.wraps装饰器模块

functools.wraps的特点:

  • 被装饰函数不受装饰器的影响
  • 装饰器的名字变成被装饰名字,外部调用到的被装饰函数的功能
  • 有错误欢迎纠正

实现一个函数执行后计算时间的功能

写程序时,经常需要对函数的运行时间进行记时,如果每个函数的前后都写上time.clock(),需要修改的代码比较多,显得代码冗余,使用修饰器可以精简代码。

普通装饰器

def tictoc(func):
    def wrapper():
        '''something'''
        begin = time.clock()
        func()
        end = time.clock()
        print('time costs: %d' % (end - start))
    #返回包装后的函数wrapper,后面会输出本函数的__name__对比区别
    return wrapper

#通过传入函数本身的方式,再返回给函数本身,主程序中可以直接调用被装饰函数
func = tictoc(func)

#除了上述方法,还可以通过下面这种方法调用装饰器后的函数
@tictoc
def func():
    def subFun():
        print('this is subFun')
    print('this is func')
func()

#@tictoc的作用和func = tictoc(func)一样

print(tictoc.__name__)
print(func.__name__)

到这里,输出一下wrapper.__name__func.__ name __
分别为:
tictoc
wrapper

这说明了func的名字变成了wrapper,这是程序设计中一个很严重的问题,丢失了被装饰函数的内容,即被装饰函数被装饰器修改了,会影响测试环节。

如何解决这个问题呢?

使用functools.wraps(func)装饰器

def tictoc(func):
    @functools.wraps(func)
    def wrapper():
        '''something'''
        begin = time.clock()
        func()
        end = time.clock()
        print('time costs: %d' % (end - start))
    #返回包装后的函数wrapper,后面会输出本函数的__name__对比区别
    return wrapper

@tictoc
def func():
    def subFun():
        print('this is subFun')
    print('this is func')
func()

#这次再打印看看
print(tictoc.__name__)
print(func.__name__)

输出如下:
tictoc
func

这次,func的名字是本身。

贴下面一段源码,深刻感受这个装饰器的作用,整体代码见github中下面这个文件:
tensorflow/models/research/slim/nets/nets_factory.py

if name not in networks_map:
    raise ValueError('Name of network unknown %s' % name)
func = networks_map[name]
@functools.wraps(func)
def network_fn(images):
    arg_scope = arg_scopes_map[name].   (weight_decay=weight_decay)
    with slim.arg_scope(arg_scope):
    return func(images, num_classes, is_training=is_training)
if hasattr(func, 'default_image_size'):
    network_fn.default_image_size = func.default_image_size

return network_fn

如果没有这个装饰器,调用func时,无法调用到net模型的函数。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值