本质上,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()
函数,不仅会运行now()
函数本身,还会在运行now()
函数前打印一行日志@log
放到now()
函数的定义处,相当于执行了语句: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可以用函数实现,也可以用类实现。