Python基础(十四)
2020-12-13 16:17
阅读:578
回顾一下之前的游戏模拟,通过装饰器给我的游戏过程扩展了开挂的功能,装饰之后每次想玩游戏的时候调用函数都会给你先把挂打开,此时你的游戏函数已经被装饰了,但是现在有一个问题,我今天想自己玩一把,不想开挂了,怎么办?我们可以给装饰器传一个参数,来控制我的装饰器的开启和关闭就可以了
def wrapper_outer(argv): # 给装饰器加一个参数,控制装饰器开启关闭
def wrapper(fn):
def inner(hero):
if argv: # 如果是True执行添加装饰
print("开启外挂!")
ret = fn(hero)
print("关闭外挂!")
return ret
else: # 如果是False,执行原函数
ret = fn(hero)
return ret
return inner
return wrapper
@wrapper_outer(True)
def play_lol(hero): # 基础函数参数
print("登陆游戏")
print("开始排位...")
print(f"选择英雄:{hero}")
print("游戏中...")
print("胜利!!!")
print("结束游戏")
return "坑比队友:xxx" # 基础函数返回值
print(play_lol("盖伦"))
运行结果:
开启外挂!
登陆游戏
开始排位...
选择英雄:盖伦
游戏中...
胜利!!!
结束游戏
关闭外挂!
坑比队友:xxx
-
刨析一下:
- 先来看装饰器和语法糖
-
@wrapper_outer(True)
先执行函数调用,函数调用返回的是我内层装饰器的函数名,相当于@wrapper
- 装饰器最外层的参数控制内层包装函数inner里面的函数部分是否执行,如果argv为真,相当于执行了包装,如果argv为假,执行原函数
-
- 通过给装饰器传参起到了控制装饰器是否生效的功能
def wrapper_outer(argv): def wrapper(fn): def inner(hero): if argv: # 为真执行这里 print("开启外挂!") ret = fn(hero) print("关闭外挂!") return ret else: # 为假执行这里 ret = fn(hero) return ret return inner return wrapper @wrapper_outer(True) # 先执行函数调用
- 注意:一旦给函数装饰过,装饰器的参数是不能变化的,因为闭包的原因参数已经被闭进去了,只能调用内层函数,无法再修改最外层的装饰器参数
flag = True def wrapper_outer(argv): def wrapper(fn): def inner(*args, **kwargs): if argv: """扩展功能""" ret = fn(*args, **kwargs) """扩展功能""" return ret else: ret = fn(*args, **kwargs) return ret return inner return wrapper @wrapper_outer(flag) def func(): pass flag = False func() # 此时flag依然是True,装饰过就不能修改参数的值
- 先来看装饰器和语法糖
评论
亲,登录后才可以留言!