python 装饰器decorator/@

decorator的作用主要是给函数动态的添加功能,它接受一个函数作为参数,并且返回一个函数。

如定义一个能打印日志的decorator:
    def log(func):
    	def wrapper(*args, **kw):
        	print('call %s():' % func.__name__)
        	return func(*args, **kw)
    	return wrapper
	@log
	def now():
    	print('2015-3-25')

以上则为now()添加了一个打印log的装饰器,调用now()并执行后输出:

	>>> now()
	call now():
	2015-3-25

即传入的参数为now()方法,相当于执行now = log(now),即首先打印日志,然后执行原始函数。

如果decorator需要传参,则需编写一个返回decorator的高阶函数:
def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

@log('execute')
def now():
    print('2015-3-25')

执行结果如下:

execute now():
2015-3-25

即相当于语句:

>>> now = log('execute')(now)

注意,使用decorator之后,函数的__name__等属性都会变为wrapper()函数的wrapper,有些依赖函数签名的代码执行就会出错,故需要最后一步,可以在wrapper前添加:@functools.wraps(func)
如:

import functools

def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

or

import functools

def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

猜你喜欢

转载自blog.csdn.net/guofeng_hao/article/details/84644139