函数装饰器简单说就是将被修饰的函数作为参数传给@符号引用的函数
import time
# def cal_time(fn):
# start = time.time()
# # test()
# fn()
# end = time.time()
# print(end - start)
def cal_decorator(fn):
def do_action():
start = time.time()
fn()
end = time.time()
print('{}函数耗时{}'.format(fn, end - start))
return do_action
@cal_decorator
def test():
print('hehe')
time.sleep(3)
print('hahahaha')
# time.time()拿到是时间戳.从1970-1-1 08:00:00 UTC+8 开始,到现在的秒数
# start = time.time()
# test()
# end = time.time()
# print(end - start)
# cal_time(test)
test()
@cal_decorator
def demo():
y = 0
for x in range(10000000):
y += x
# start = time.time()
# demo()
# end = time.time()
# print(end - start)
# cal_time(demo)
demo()
@cal_decorator
def foo():
y = 0
for x in range(10000000):
y += x
foo()
装饰器示例
1:无参的函数
def check_time(action):
def do_action():
action()
return do_action
@check_time
def go_to_bed():
print('去睡觉')
go_to_bed()
上面代码理解装饰器执行行为可理解成
result = check_time(go_to_bed) # 把go_to_bed 当做参数传入给 check_time函数,再定义一个变量用来保存check_time的运行结果
result() # check_time 函数的返回值result是一个函数, result()再调用这个函数,让它再调用go_to_bed函数
2:被装饰的函数有参数:
def can_play(fn):
def do_action(name, game, *args, **kwargs):
if kwargs.get('clock', 21) < 21:
fn(name, game)
else:
print('时间太晚了,不能玩儿了')
return do_action
@can_play
def play_game(name, game):
print(name + '正在玩儿' + game)
play_game('张三', '王者荣耀')
play_game('李四', '绝地求生', clock=22)
3:装饰器带参数
# clock = int(input('请输入时间:'))
def can_play(clock):
def handle_action(fn):
def do_action(name, game, *args, **kwargs):
if clock < 21:
fn(name, game)
else:
print('太晚了,不能玩儿了!!!')
return do_action
return handle_action
@can_play(21)
def play_game(name, game):
print(name + '正在玩儿' + game)
play_game('张三', '王者荣耀')
play_game('李四', '绝地求生')
4:被装饰的函数有不定长参数
def test(cal):
def do_cal(*args,**kwargs):
cal(*args,**kwargs)
return do_cal
@test
def demo(*args):
sum = 0
for x in args:
sum +=x
print(sum)
demo(1, 2, 3, 4)
5:装饰器中的return
def test(cal):
def do_cal(*args,**kwargs):
return cal(*args,**kwargs) # 需要再这里写return语句,表示调用函数,获取函数的返回值并返回
return do_cal
@test
def demo(a,b):
return a + b
print(demo(1, 2)) #3
总结:
一般情况下为了让装饰器更通用,可以有return
装饰器提高:
def outer_check(base_permission):
def check_permission(action):
def do_action(my_permission):
if my_permission & base_permission:
return action(my_permission)
else:
return '对不起,您不具有该权限'
return do_action
return check_permission
READ_PERMISSION = 1
WRITE_PERMISSION = 2
EXECUTE_PERMISSION = 4
@outer_check(base_permission=READ_PERMISSION)
def read(my_permission):
return '读取数据'
@outer_check(base_permission=WRITE_PERMISSION)
def write(my_permission):
return '写入数据'
@outer_check(base_permission=EXECUTE_PERMISSION)
def execute(my_permission):
return '执行程序'
print(read(5))