修改全局变量时,可变类型和不可变类型的区别
先说结论:
嵌套函数(如闭包,修饰器等),需要修改全局变量时,如果全局变量是不可变类型,那么在修改全局变量时要先写‘global 变量名‘,此时才可以修改;如果全局变量是可变类型,则可以直接修改。
底层机制为:函数内修改全局变量时,不可以更改全局变量的内存地址路径。调用的话是随便的,不需要进行其他特殊操作。
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。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')

更多精彩