python装饰器

装饰器就是一个普通的函数,它一般用于将传入的函数或者类做一定的处理,返回新的函数或者类。

不带参数的函数装饰器

假如我们需要在每个函数的开始和结束处打印一条日志,我们就可以通过装饰器来实现

#定义一个装饰器
def add_log(f):
    def deco(*args, **kwargs):
        print "start of function %s" % f.func_name
        re = f(*args, **kwargs)
        print "end of function %s" % f.func_name
        return re
    return deco

#用装饰器装饰两个函数
@add_log
def add(x, y):
    return x + y

@add_log
def dec(x, y):
    return x - y

print add(1, 2)
print dec(1, 2)
输出:
> start of function add
> end of function add
> 3
> start of function dec
> end of function dec
> -1

其中的@add_log相当于add = add_log(add)和dec = add_log(dec)

这里有一个问题,打印add.func_name发现它等于deco,如果我们的程序对函数名有依赖的话,显然加了这个装饰器就会影响它的功能。
幸好python内置的functools模块可以将函数原来的属性全部复制到新函数上。

将原来的装饰器改为:

from functools import wraps
def add_log(f):
    @wraps(f)
    def deco(*args, **kwargs):
        print "start of function %s" % f.func_name
        re = f(*args, **kwargs)
        print "end of function %s" % f.func_name
        return re
    return deco

这样装饰后的add的函数名就是add了

带参数的函数装饰器

假如我们需要在函数的开始和结尾处打印的日志里加上作者的信息,我们可能通过给装饰器加参数实现:

from functools import wraps
#定义一个装饰器
def add_log(author):
    def first_deco(f):
        @wraps(f)
        def deco(*args, **kwargs):
            print "start of function %s defined by %s" % (f.func_name,author)
            re = f(*args, **kwargs)
            print "end of function %s" % f.func_name
            return re
        return deco
    return first_deco
#用装饰器装饰两个函数
@add_log('xb')
def add(x, y):
    return x + y        

@add_log("xb")
def dec(x, y):
    return x - y


print add(1, 2)
print dec(1, 2)

print add.func_name
输出
start of function add defined by xb
end of function add
3
start of function dec defined by xb
end of function dec
-1
add

其中的@add_log相当于add = add_log(‘xb’)(add)和dec = add_log(‘xb’)(dec)

参数为类的情况类似这里就不再举例了


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值