- 装饰器基本就是一个闭包问题
#### 第一波 ####
def foo():
print('foo')
foo # 表示是函数
foo() # 表示执行foo函数
#### 第二波 ####
def foo():
print('foo')
foo = lambda x: x + 1
foo() # 执行lambda表达式,而不再是原来的foo函数,因为foo这个名字被重新指向了另外一个匿名函数
函数名仅仅是个变量,只不过指向了定义的函数而已,所以才能通过 函数名()调用,如果 函数名=xxx被修改了,那么当在执行 函数名()时,调用的就不知之前的那个函数了。
使用装饰器计算一段代码的执行时间
import time
def cal_time(fn): # fn = demo
print('我是cal_time函数,我被调用了')
def inner():
print('inner函数被调用了')
start = time.time()
fn()
end = time.time()
print('代码一共花了{}秒'.format(end - start))
return inner # cal_time里要返回 inner函数
# Python装饰器的语法
@cal_time # 1. 调用 cal_time 函数,将demo函数当做参数传给 cal_time 函数
def demo():
x = 0
for i in range(1, 10):
x += i
print('1到100000000所有整数之和是{}'.format(x))
demo() # 此时再使用demo,不再是第19行的demo函数了,而是 cal_time里的inner函数
- 被装饰的函数有返回值
在这里需要在内置函数中将外置函数参数进行一个赋值
import time
def cal_time(fn): # fn ==> demo
def inner():
start = time.time()
a = fn()
end = time.time()
print('耗时{}秒'.format(end - start))
return a
return inner
@cal_time
def demo():
x = 0
for i in range(1, 100000000):
x += i
return x
result = demo()
print('数字相加的结果是{}'.format(result))
- 被装饰的函数有参数
在这里需要在内置函数中加参数
def can_play(fn):
def inner(a, b, *args, **kwargs):
clock = kwargs.get('clock', 21)
if clock < 22:
fn(a, b)
else:
print('太晚了,别玩了,赶紧睡去')
return inner
@can_play
def play_game(name, game):
print('{}正在玩儿{}'.format(name, game))
play_game('小明', '王者荣耀', 'hello', 'good', 'yes', x=10, y=200)
def hundred(fn):
def inner(a, b):
s = fn(a, b)
return s
return inner
@hundred
def add(a, b):
return a + b
res = add(17, 13)
print(res)
- 装饰器有参数
装饰器中有参数需要再进行一个函数嵌套
clock = int(input('请输入当前的时间:'))
def can_play(x):
# print('can_play被调用了')
def outer(fn):
# print('outer被调用了')
def inner(a, b, **kwargs):
# print('inner被调用了')
if x < 22:
fn(a, b)
else:
print('{}太晚了,别玩儿了,乖赶紧睡'.format(a))
return inner
return outer
@can_play(clock)
def play_game(name, game):
print('{}正在玩儿{}'.format(name, game))
play_game('佳佳', '和平精英')