因为高阶函数的存在,可以接受函数传参,这就让不改变原有函数的前提下,“装饰”原有函数成为可能。也就是增强其功能。
不带参数的装饰器实现不带参数的装饰器至少需要这样两步操作:

可以看出,不带参数的装饰器实现有两个步骤:
- 传入原函数名
- 传入原函数参数列表,增加功能代码,调用原函数
 两个步骤之间的链接,是用return返回函数名进行指向(闭包)。
类比不带参数的装饰器实现步骤,每一次传参,就需要定义一次函数,并完成内外层函数的指向调用,类似与递归。
因此不难想象,当我们本身的装饰器也需要参入特定参数时,我们就需要把不带参数的装饰器再进行一次封装,在传入原函数前,增加一个传参和指向的过程。
如下:

可以看出,带参数的装饰器实现就多了一个传送装饰参数的过程,就多了一层。
不带参数的装饰器
        def log_decorator(f):
            def wrapper(*args,**kw):
                print '%s()...'%f.__name__
                return f(*args,**kw)
            return wrapper
带参数的装饰器
 def log(prefix):
        def log_decorator(f):
            def wrapper(*args,**kw):
                print '[%s]%s()...'%(prefix,f.__name__)
                return f(*args,**kw)
            return wrapper
        return log_decorator从上面两个实例对比可以看出,带参数与不带参数,就是多了一层封装,多的这一层,提供了传参的入口。
类装饰器类装饰器,相比函数装饰器,具有灵活度大、高内聚、封装性等优点。
class Foo(object):
    def __init__(self, func):
        self._func = func
    def __call__(self):
        print 'class decorator runing'
        self._func()
        print 'class decorator ending'
@Foo
def bar():
    print 'bar'
bar()使用装饰器极大复用了代码,但是也有缺点就是原函数元信息不见了,比如函数的docstring、name、参数列表
装饰器
def logged(func):
    def with_logging(*args, **kwargs):
        print func.__name__ + 'was called'
        return func(*args, **kwargs)
    return with_logging
函数
@logged
def f(x):
    """does some math"""
    return x + x*x
# 等价于f = logged(f)不难发现,函数f被with_logging取代了,当然它的docstring,name就是变成了with_logging函数的信息了。
print f.__name__    # 'with_logging'
print f.__doc__       # 'None'怎么解决,这里有个functools.wraps,wraps本身也是一个装饰器,它能把元函数的元信息拷贝到装饰器函数中,这使得装饰器函数也有和原函数一样的元信息了。
from functools import wraps
def logged(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print func.__name__ + 'was called'
        return func(*args, **kwargs)
    return with_logging
@logged
def f(x):
    """does some math"""
    return x + x*x
print f.__name__       # 'f'
print f.__doc__          # 'does some math'@staticmethod
@classmethod
@property
装饰器的顺序@a
@b
@c
def f():
    pass
# 等效于 
f = a(b(c(f))) 
		




 随时随地看视频
随时随地看视频 
				 
				 
				 
				 
				