函数的嵌套定义
global nonlocal关键字
'''
global:将局部的变量作用域提升为全局变量
当全局已经拥有一个变量,在函数内部定义一个有global修饰的变量,那么这两个就是一个变量
想要在函数定义一个全局变量,全局要没有同名的变量
+=也属于改变自身的范畴,当在外面有全局变量,函数内部要对该变量自身进行运算,必须使用global修饰
nonlocal:
将变量提升为嵌套作用域(有两个函数,内部函数的内部变量的作用域提升为外层函数的变量作用域),外部函数必须已存在一个同名变量
如果局部想改变嵌套局部变量的值(发生地址的变化),可以用nonlocal声明该变量
+=,-=,等对自身的运算也算对自身改变,也要用nonlocal
'''
闭包及闭包的运用场景
'''
闭包:被函数包裹的函数,也可以理解为函数内部的函数
闭包的应用场景:
闭包中使用的变量可以被外层函数所传递 -- 外层函数可以为闭包传递参数
延迟执行
开放封闭原则:在不修改源代码和调用方式的情况下给函数添加新功能
'''
装饰器
'''
满足开放封闭原则的闭包应用
@outer语法来调用outer,规定传入被装饰的函数对象,所以参数固定为一个,接收被装饰的函数对象
def outer(func):
不能确定被装饰的函数的参数:来者不拒,用可边长来接受
def inner(*args, **kwargs):
pass # 新功能位
res = func(*args, **kwargs) # 解压带给原功能
pass # 新功能位
return res
return inner
使用装饰器(outer),得到新功能(inner)
用被装饰的函数名去接受装饰器的执行结果,调用装饰器时传入被装饰的函数对象
@outer # fn = outer(fn) = inner
def fn(): pass
'''
一个函数被多次装饰
'''
def outer(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
return res
return inner
def check_user(func):
def inner(*args, **kwargs):
# 账号的验证功能
user = args[0] # type: str
if not (user.isalpha() and len(user) >= 3):
print('账号不合法')
return False
res = func(*args, **kwargs)
return res
return inner
def check_pwd(func):
def inner(*args, **kwargs):
pwd = args[1]
if len(pwd) < 3:
print('密码不合法')
return False
res = func(*args, **kwargs)
return res
return inner
def format_return(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
if res:
return '登录成功'
return '登录失败'
return inner
# 登录的原功能
@format_return
@check_user
@check_pwd
def login(user, pwd):
if user == 'owen' and pwd == '123':
return True
return False
user = input('user: ')
pwd = input('pwd: ')
res = login(user, pwd)
print(res)
# 执行过程:调用login => 进入第一个装饰器(format_return)的inner => 进入第二个装饰器(check_user)的inner => 进入第三个装饰器(check_pwd)的inner => 开始返回,从第三个返回到第二个再返回到第一个,最后返回到外界调用的位置
'''