一、
# 作用:将 L 与 E(E中的名字需要提前定义) 的名字统一
# 应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值
# 案例:
def outer():
num = 10
print(num) # 10
def inner():
nonlocal num
num = 20
p77rint(num) # 20
inner()
print(num) # 20
二、
1.不能修改被装饰对象(函数)的源代码(封闭)
2.不能更改被修饰对象(函数)的调用方式,且能达到增加功能的效果(开放)
三、
# 把要被装饰的函数作为外层函数的参数通过闭包操作后返回一个替代版函数
# 被装饰的函数:fn
# 外层函数:outer(func) outer(fn) => func = fn
# 替代版函数: return inner: 原功能+新功能
def fn():
print("原有功能")
# 装饰器
def outer(tag):
def inner():
tag()
print(新增功能")
return inner
fn = outer(fn)
fn()
四、
def outer(f):
def inner():
f()
print("新增功能1")
return inner
def wrap(f):
def inner():
f()
print("新增功能2")
return inner
@wrap # 被装饰的顺序决定了新增功能的执行顺序
@outer # <==> fn = outer(fn): inner
def fn():
print("原有功能")
五、
def check_usr(fn): # fn, login, inner:不同状态下的login,所以参数是统一的
def inner(usr, pwd):
# 在原功能上添加新功能
if not (len(usr) >= 3 and usr.isalpha()):
print('账号验证失败')
return False
# 原有功能
result = fn(usr, pwd)
# 在原功能下添加新功能
return result
return inner
@check_usr
def login(usr, pwd):
if usr == 'abc' and pwd =='123qwe':
print('登录成功')
return True
print('登录失败')
return False
# 总结:
# 1.login有参数,所以inner与fn都有相同参数
# 2.login有返回值,所以inner与fn都有返回值
"""
inner(usr, pwd):
res = fn(usr, pwd) # 原login的返回值
return res
login = check_usr(login) = inner
res = login('abc', '123qwe') # inner的返回值
六、
def wrap(fn):
def inner(*args, **kwargs):
print('前增功能')
result = fn(*args, **kwargs)
print('后增功能')
return result
return inner
@wrap
def fn1():
print('fn1的原有功能')
@wrap
def fn2(a, b):
print('fn2的原有功能')
@wrap
def fn3():
print('fn3的原有功能')
return True
@wrap
def fn4(a, *, x):
print('fn4的原有功能')
return True
fn1()
fn2(10, 20)
fn3()
fn4(10, x=20)
七、
# 了解
def outer(input_color):
def wrap(fn):
if input_color == 'red':
info = ' 33[36;41mnew action33[0m'
else:
info = 'yellow:new action'
def inner(*args, **kwargs):
pass
result = fn(*args, **kwargs)
print(info)
return result
return inner
return wrap # outer(color) => wrap
color = input('color: ')
@outer(color) # @outer(color) ==> @wrap # func => inner
def func():
print('func run')
func()