装饰器
1.nonlocal关键字
nonlocal是将local和eclosing的名字进行了统一,应用场景有:想要在被嵌套的函数中修改外部函数变量名字的值
例子:
def outter():
num=10
print('1:'num) 10
def inner(): 如果此时nonlocal的话,那么num3就被变成10,但是如果global的话,那么nonlocal就不可以用,只能修改函数内部值,不可以修改全局
num=20
print('2:'num) 20
inner()
print('3':,num) 20
outter()
print('4:'num) 10
查找元素名字的加载顺序是LEGB,加载顺序是BGEL
2.开放封闭原则:1,在不修改源代码和调用方式的情况下新增功能 (开放)
2.满足不改变调用方式和源代码的情况 (封闭)
装饰器就是要在满足开放封闭的原则下,进行的一个函数的使用
3.装饰器:要把被装饰的函数作为外层函数的参数通过闭包操作后返回的一个替代版函数,被装饰的函数时原来的fn(),加强版的函数是返回版的fn()。
def wrapper(tag):
def inner(): #加强版的vase()
tag() #原来的vase()
print('新增功能‘)
return inner #返回的加强版的vase()
vase=wrapper(vase) #加强后vase从新赋值给vase
vase()
def vase(): #原来的vase
print('原有功能’)
vase()
3.2笑笑语法|语法糖
@wrapper
这个要求将被装饰的函数置于函数的下方
def wrapper(tag):
def inner():
tag()
print(’新增功能‘)
return inner #此时的inner是一个函数地址
#vase=wrapper(vase)
vase()
@wrapper
def vase():
print('原有功能‘)
vase()
3.3有参有返的装饰器
1,被装饰函数有参数,新函数(inner和返回的fn)都要有相同的参数
2.被装饰的函数有返回值,新函数(inner和返回的fn)都要有返回值
账号验证,要求账号长度不小于3,且为英文字母组成
is_login=False #判断用户的登陆状态
def check_usr(fn):
def inner(usr,pwd):
if not (len(usr)>3 and usr.isalpha()):
print('密码验证失败‘)
return False
print(’密码验证通过‘)
result=fn(usr,pwd)
return result
return inner
密码验证,要求密码长度不小于3,且为字母汉字组成
def outter(fn):
def inner(usr,pwd):
if not (len(pwd)>3 and pwd.isalnum()):
print('密码验证失败’)
return False
print(‘密码验证通过’)
return fn(usr,pwd)
return inner
@wrapper #谁在上就先打印谁
@outter
用户的登陆系统
def login(usr,pwd):
if usr=='egon' and pwd=='123':
print('登录成功’)
return True
print(‘登录失败’)
return False
res=login('abc','123qwe')
print(res)
3.4装饰器结合可变长参数
def wrapper(fn):
def inner(*args,**kwargs):
result=fn(*args,**kwargs)
print('后增功能‘)
return result
return inner
@wrapper
def fn1():
print('原有功能’)
@wrapper()
def fn2(a,b):
print('原有功能‘)
@wrapper
def fn3():
print('原有功能’)
return True
@wrapper
def fn4(a,b):
print('原有功能‘)
return True
fn1()
fn2()
fn3()
fn4()