本质上,decorator就是一个返回函数的高阶函数

e.g.定义一个能打印日志的decorator:

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

把decorator置于函数的定义处:

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

由于log()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数。

3层嵌套的效果是这样的:

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

为防止有些依赖函数签名的代码执行出错,需要把原始函数的__name__等属性复制到wrapper()函数中

import functools

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

在面向对象(OOP)的设计模式中,decorator被称为装饰模式。OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。Python的decorator可以用函数实现,也可以用类实现。