Python基础(十三)
2020-12-13 15:52
标签:安全 胜利 修改 xxx 重要 print outer lol 标准模式 闭包:内层函数调用外层函数的变量就是闭包(不能是全局变量) 检测闭包的方法 如何在全局空间中调用内部函数 将变量常驻内存,供后续代码使用 利用语法糖装饰 此时,装饰器的雏形就出来了 Python基础(十三) 标签:安全 胜利 修改 xxx 重要 print outer lol 标准模式 原文地址:https://www.cnblogs.com/tianlangdada/p/11616788.html今日主要内容
一、闭包
(一)什么是闭包
def func1():
a = 10
def func2():
print(a) # 内层函数调用外层函数的变量,这就是一个闭包
func1()
函数名.__closure__
.__closure__
检测的是函数名,判断这个函数是否是闭包def func1():
a = 10
def func2():
print(a) # 调用外层变量a,是闭包
print(func2.__closure__) # 判断func2是否是闭包
func1()
运行结果:
(
def func1():
a = 10
def func2():
a = 10
print(a) # 使用自身函数变量a,不是闭包
print(func2.__closure__)
func1()
运行结果:
None
def func1():
a = 10
def func2():
print(a)
return func2 # 返回内层函数的函数名
f = func1() # 此时f就是func2
f() # 调用内层函数func2
print(f.__closure__)
运行结果:
10
(
(二)闭包的作用
def outer():
lst = [1,2,3,4,5]
def inner():
return lst
return inner
f = outer()
f_lst = f()
print(f_lst)
运行结果:
[1,2,3,4,5]
(三)闭包的应用
二、装饰器初识
(一)软件开发的六大原则(了解)
(二)装饰器依据——开闭原则
(三)装饰器引入
相信大多数人都玩LOL,我们模拟一次游戏过程:
def play_lol():
print("登陆游戏")
print("开始排位...")
print("游戏中...")
print("失败...")
print("结束游戏")
play_lol()
运行结果:
登陆游戏
开始排位...
游戏中...
Virtory
结束游戏
def play_lol():
print("开启外挂!") # 添加开启外挂功能
print("登陆游戏")
print("开始排位...")
print("游戏中...")
print("胜利!!!")
print("结束游戏")
print("关闭外挂!") # 添加关闭外挂功能
play_lol()
运行结果:
开启外挂!
登陆游戏
开始排位...
游戏中...
胜利!!!
结束游戏
关闭外挂!
def play_lol():
print("登陆游戏")
print("开始排位...")
print("游戏中...")
print("胜利!!!")
print("结束游戏")
def new_play(): # 将上面代码前后包装成了一个新的函数,没有改变源码
print("开启外挂!")
play_lol()
print("关闭外挂!")
new_play()
运行结果:
开启外挂!
登陆游戏
开始排位...
游戏中...
胜利!!!
结束游戏
关闭外挂!
play_lol
这个函数,但此时我们访问调用的是new_play()
这个函数,相当于改变了调用,还是违背了开闭原则,没有达到扩展的效果,此时我们就需要对这段代码稍作变化def play_lol():
print("登陆游戏")
print("开始排位...")
print("游戏中...")
print("胜利!!!")
print("结束游戏")
def wrapper(fn): # 装饰器雏形
def inner():
print("开启外挂!")
fn()
print("关闭外挂!")
return inner
func = wrapper(play_lol) # 调用装饰器函数将我基础函数传入进去包装
play_lol = func # 返回的是包装函数,将包装函数重命名成我原来的函数
play_lol() # 调用此函数
运行结果:
开启外挂!
登陆游戏
开始排位...
游戏中...
胜利!!!
结束游戏
关闭外挂!
return inner
:装饰器的返回值是内层函数的函数名,真正进行包装扩展的是内层函数def wrapper(fn): # 装饰器雏形
def inner():
print("开启外挂!")
fn()
print("关闭外挂!")
return inner
func = wrapper(play_lol) # 调用装饰器函数将我基础函数传入进去包装
play_lol = func # 返回的是包装函数,将包赚函数重命名成我原来的函数
play_lol() # 调用此函数
func = wrapper(play_lol) # 调用装饰器函数将我基础函数传入进去包装
play_lol = func # 返回的是包装函数,将包赚函数重命名成我原来的函数
@wrapper # 语法糖
def play_lol():
print("登陆游戏")
print("开始排位...")
print("游戏中...")
print("胜利!!!")
print("结束游戏")
装饰器雏形
def wrapper(fn):
def inner():
"""扩展功能"""
fn()
"""扩展功能"""
return inner
@wrapper
def func():
pass
func()
游戏模拟继续进行
def wrapper(fn): # 装饰器雏形
def inner(hero): # 套到装饰器中内层包装函数参数
print("开启外挂!")
fn(hero) # 基础函数参数
print("关闭外挂!")
return inner
@wrapper
def play_lol(hero): # 基础函数参数
print("登陆游戏")
print("开始排位...")
print(f"选择英雄:{hero}")
print("游戏中...")
print("胜利!!!")
print("结束游戏")
play_lol("盖伦")
运行结果:
开启外挂!
登陆游戏
开始排位...
选择英雄:盖伦 # 传入的参数
游戏中...
胜利!!!
结束游戏
关闭外挂!
def wrapper(fn): # 装饰器雏形
def inner(hero):
print("开启外挂!")
ret = fn(hero) # 接收基础函数的返回值
print("关闭外挂!")
return ret # 返回包装后的函数的返回值
return inner
@wrapper
def play_lol(hero): # 基础函数参数
print("登陆游戏")
print("开始排位...")
print(f"选择英雄:{hero}")
print("游戏中...")
print("胜利!!!")
print("结束游戏")
return "坑比队友:xxx" # 基础函数返回值
print(play_lol("盖伦"))
运行结果:
开启外挂!
登陆游戏
开始排位...
选择英雄:盖伦
游戏中...
胜利!!!
结束游戏
关闭外挂!
坑比队友:xxx # 返回值
装饰器标准模式(非常重要)
def wrapper(fn):
def inner(*args, **kwargs):
"""扩展功能"""
ret = fn(*args, **kwargs)
"""扩展功能"""
return ret
return inner
@wrapper
def func():
pass
func()
上一篇:java 比较时间的几种方法
下一篇:关于java的数组