一、何为装饰器? 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。装饰器是可调用的对象,其参数是另一个函数(被装饰的函数)。装饰器可能会处理被装饰的函数,然后把它返回,或者将其替换成另一个函数或可调用对象。
二、装饰器例子 一个装饰器的例子:
def deco(func): def inner(*args, **kw): print('running inner()') return func(*args, **kw) return inner @deco def target(): print('running target()')上述代码就相当于:
def target(): print('running target()') target = deco(target())两种写法的结果一样,最终结果都是decorate(target)返回的函数,而不是原来的函数target。 装饰器的特点:一是能把被装饰的函数替换成其他函数,二是在加载模块是立即执行 结果:
>>> target <function deco.<locals>.inner at 0x112138510> >>> target() running inner() running target()当你看见过flask的路由,你会发现语法糖中会写路由地址(@app.route(‘/login’, methods=[‘GET’,’POST’])),以及其他参数信息。 所以我们想修改以上程序内容,使它能处理或接受的信息更加丰富,如果装饰器(上例的deco)本身需要传入参数,那就需要编写一个返回装饰器(上例的deco)的高阶函数,写出来会更复杂。
def log(text): def deco(func): def inner(*args, **kw): print('%s %s():' % (text, func.__name__)) return func(*args, **kw) return inner return deco @log('execute') def target(): print('running target()')这样我们就可以从语法糖接受并输出text的数据,这个数据不会影响被装饰的函数。 来看看输出
>>> target <function log.<locals>.deco.<locals>.inner at 0x1121386a8> >>> target() execute target(): running target()