开发者学堂课程【Python入门 2020年版:高级装饰器】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/639/detail/10419
高级装饰器
内容介绍:
一、装饰器回顾
二、高级装饰器
一、装饰器回顾
1、定义
装饰器其实就是一个函数,我们通过之前所写的一个案例进行回顾装饰器的定义
l 输入基本代码
def play_ game (name, game):
print(name + ' 正在玩儿
' + game)
l 判断代码是否能够正常运行
def can_ play(fn):
print(
'外部函数被调用了')
def inner():
pass
return inner
@can_ play
此时已经写入了装饰器,一旦写入就会去调用can_ play函数,运行之后显示:外部函数被调用了。
然后 play game 就会传给fn,再去调用play game时,它就已经不是原来的了。
l 最终代码如下:
def can_ play(fn):
print
('外部函数被调用了')
def inner(name, game):
fn(name, game )
return inner
@can_ play
def play_ game (name, game):
print(
name + ' 正在玩儿' + game)
play_ game
('张三', '王者荣耀')
l 运行结果为:
l 张三正在玩儿王者荣耀
2、装饰器作用:
(1) 调用can_ play
函数
(2) 被装饰的函数传给fn
(3) 再次写play_ game
对应的为返回值return inner
3、进行时间限定
l 具体代码:
def can_ play(fn):
print
( '外部函数被调用了')
def inner(name, game, **kwargs):
clock = kwargs .get('clock', 21)
if clock >= 21:
print
('太晚了不能玩儿游戏了')
else:
fn(name, game)
return inner
@can_ _play
def play_ game(name, game):
print
(name +'正在玩儿' + game)
play_ game
('张三', '王者荣耀',clock=22)
l 代码解释:
由于多了clock 参数,因此此时运行会报错,我们需要对其进行解释,所以输入**kwargs
,但是直接通过kwargs=('clock', 22}
传入会出现一个问题,即当没有传入clock值时就去运行,系统会崩溃,因此我们需要写为clock = kwargs .get('clock', 21)
l 运行结果为:
太晚了不能玩儿游戏了,如果将时间限制改为20,没有超过时间限制,则运行结果为张三正在玩儿游戏。
二、高级装饰器
1、引言
我们可以看到像上述所讲的装饰器还是不够强大,需要我们人为的传入一个参数,而高级的传输器就可以很好的解决上述所出现的问题。
2、具体代码
def can_ play(clock):
print
(‘最外层函数被调用了,clock={}’.format(clock))
def handle_ action(fn):
def do_ action(name,game):
if clock < 21:
fn(name,game)
else:
print
(‘太晚了,不能玩儿游戏了’)
return do_ action
return handle_ action
@can_ play(20)
def play_ game(name, game):
print
(name + ' 正在玩儿'+ game)
play_ game
3、代码解释
@can_ play(20)
就可以表示函数,即装饰器函数带参数。因此高级装饰器的结果就更为复杂一些一旦输入了装饰器,最外层函数就会调用,然后将22传给 clock。
需要注意的是,返回时can-play返回return handle_ action
的值,然后return do_ action
再表示 handle_ action
的返回值。
上述就完成了第一步,第二步需要将play_ game
给到fn,此时调用的就是do_ action了,运行后会发现报错,因为我们需要在def do_ action(name,game):
中传入参数,然后再通过判断时间if clock < 21:
,决定是否可以进行继续玩游戏。
上述举例就可以体现高级装饰器的强大之处,不需要对原有的部分代码进行任何修改,只需要再进行下一步的修饰。
如果直接写@can_ play
,即不加()直接调用,调用的就是print(‘最外层函数被调用了,clock={}’.format(clock)
)这一层;
如果写作
@can_ play(12)
,调用的时候首先调用 print(‘最外层函数被调用了,clock={}’.format(clock)
),并将值给到 clock,即调用can_ play
函数,并将12传递给clock变量;紧接着再调用handle_ action
方法,把play_ game
传递给 fn;
紧接着再调用play_ game
,其实调用的就是 do_ action
。