先说结论:
嵌套函数(如闭包,修饰器等),需要修改全局变量时,如果全局变量是不可变类型,那么在修改全局变量时要先写‘global 变量名‘,此时才可以修改;如果全局变量是可变类型,则可以直接修改。
底层机制为:函数内修改全局变量时,不可以更改全局变量的内存地址路径。调用的话是随便的,不需要进行其他特殊操作。
for一颗栗子
from functools import wraps tag = False #不可变类型的全局变量 def auth(name=None): def app(func): @wraps(func) def check(*args,**kwargs): global tag #声明全局变量 if tag == False: name = input('your name:').strip() pwd = input('your password:').strip() with open('c.txt',mode='rt',encoding='utf-8') as f: dic = eval(f.read()) #eval可以理解为将内容原封不动的输出,原来是字典,输出还是字典 if name in dic and dic[name] == pwd: print('login successful') tag = True #修改不可变类型的全局变量,使后续函数不用再次认证 res=func(*args,**kwargs) return res else: print('error') else: res = func(*args,**kwargs) return res return check return app @auth() def index(): print('from index') index() @auth() def home(name): print('welcome %s to home' %name) home('egon')
上下两个例子分别使用了三层和两层函数,注意两者修饰器引用上的区别,还有全局变量和函数内变量之间的关系(name)
from functools import wraps tag = {'name':None,'pwd':False} #字典是可变类型,修改字典时不会修改tag所对应的数据路径 def app(func): @wraps(func) def check(*args,**kwargs): if tag['name'] and tag['pwd']: res = func(*args,**kwargs) return res else: name = input('your name:').strip() pwd = input('your password:').strip() with open('c.txt',mode='rt',encoding='utf-8') as f: dic = eval(f.read()) if name in dic and dic[name] == pwd: print('login successful') tag['name']=True tag['pwd']=True res=func(*args,**kwargs) return res else: print('error') return check @app def index(): print('from index') index() @app def home(name): print('welcome %s to home' %name) home('egon')
作者:real-admin
原文:https://www.cnblogs.com/realadmin/p/10049224.html
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦