专注于
IT技术和业内交流

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)

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

未经允许,不得转载本站任何文章:代码山 » python装饰器

分享到:更多 ()

专注品牌化高端网站建设

商务服务联系我们