当然,必须承认,装饰器带参数后,看起来更加复杂,需要多嵌套一层函数,由最外层的函数接受参数,里层函数才是真正的装饰器。使用装饰器时,会首先运行带参数的最外层函数,返回装饰器,这一步Python会自动帮我们完成。所以,带参数的装饰器甚至可以这么使用:
h = language('中文') @h def do_something(name): print('你好,{}!'.format(name))
3.4 多层装饰器装饰器也是可以多层嵌套使用的,也就是说,一个函数可以通过是被多个装饰器所装饰,执行顺序是从下到上的优先顺序加载装饰:
# -*- coding: utf-8 -*- import time print(1) def func(f): print(2) def inner_func(*name1, **name2): print('{}函数开始运行……'.format(f.__name__)) f(*name1, **name2) print('{}函数结束运行……'.format(f.__name__)) print(3) return inner_func print(4) def timmer(f): print(5) def inner_timmer(*args, **kwargs): print('开始计时……') start_time = time.time() f(*args, **kwargs) end_time = time.time() print('开始结束……') time_cost = end_time - start_time print('{}函数运行时长为:{}秒'.format(f.__name__, time_cost)) print(6) return inner_timmer print(7) @func @timmer def do_something(name): time.sleep(1) print('你好,{}!'.format(name)) print(8) def do_something_2(name): time.sleep(1) print('你好,{}!'.format(name)) if __name__ == '__main__': print(9) do_something(name='姚明') print('-------------------------') func(timmer(do_something_2))(name='姚明') # 执行效果与上面使用了@符号的do_something一样
输出结果:
1
4
7
5
6
2
3
8
9
inner_timmer函数开始运行……
开始计时……
你好,姚明!
开始结束……
do_something函数运行时长为:1.0004358291625977秒
inner_timmer函数结束运行……
-------------------------
5
6
2
3
inner_timmer函数开始运行……
开始计时……
你好,姚明!
开始结束……
do_something_2函数运行时长为:1.000028133392334秒
inner_timmer函数结束运行……