知识点总结

全局变量和局部变量

# 全局变量在局部重新赋值会报错,无论是可变数据类型还是不可变数据类型

user = {}

def outer():
    if user:
        print(user)
    user={1:2}
    
# 报错信息:UnboundLocalError: local variable 'user' referenced before assignment (局部变量没有被定义)

#原因:
变量user在函数内部重新定义了,系统不知道user到底是全局变量还是局部变量,如果没有user={1:2},那么最后python会解析user为全局变量

#这种情况不会报错
user = {}

def outer():
    if user:
        print(user)
    user={1:2}


#如果只是修改可变类型的数据,则直接修改的是全局变量的值,user这个变量从始至终都是全局变量的这个user
user={}
def outer():
    if user:
        print(user)
    user[1]=2

#总结:
变量的赋值就会在内存中的栈区和堆区开辟空间存数据,而名称空间是堆区中的一块空间存储变量名和栈区的变量名地址的对应关系,每次赋值名称空间重新产生变量名和变量名的地址的新的对应关系。

函数外的user变量一开始被定义为全局变量,存在全局名称空间中;
如果函数内部没有定义user这个变量,调用user就是调用全局的这个user变量
但是如果函数内部已经定义了局部变量,那就会调用函数内部的这个变量,这个程序会报错,因为调用变量user在定义变量之前,在调用的时候根本没有这个变量,所以才会有报错

全局变量

user={'usr':'lxx','ps':ddd,'money':100}
def logout():
    if not user:
        print('user为空')
        return
    global user
    res = user['usr']
    user = {}
    
#报错信息:SyntaxError: name 'user' is used prior to global declaration
#原因:函数体内调用user这个变量,由于函数体内并没有user这个变量,根据LEGB原则,调用全局变量user,在第一次调用后,再次声明为全局变量,则就相当于变量未定义先引用,这个时候python无法识别之前引用的user变量是什么类型,所以会报错

#解决方案,在调用变量之前声明变量类型
user={'usr':'lxx','ps':ddd,'money':100}
def logout():
   global user
    if not user:
        print('user为空')
        return
    res = user['usr']
    user = {}
    

局部作用域和全局作用域

# 变量的查找顺序是LEGB,局部变量-内嵌外层局部变量—全局变量-内置变量
#因为python 3的存储结构是堆栈的存储结构,先定义的在名称空间中的对应关系会排在前面,会先被遍历

# 案例1: 结果为2,因为python解释器读到了inner()这个函数内的变量
a=3
def outer():
    a=1
    def inner():
        a=2
        print(a)
    inner()
outer()

#案例2:结果是1,因为inner()这个函数体内部并没有找到a,在它外层的嵌套函数outer()函数体外面找到了a这个变量,所以引用这个变量a的值
a=3
def outer():
    a=1
    def inner():
        print(a)
    inner()
outer()

#案例3: 结果是3,因为inner()这个函数内部以及外部函数outer()都没有找到a这个变量,所以只能找到函数外部的局部变量a,所以引用了局部变量a的值
a=3
def outer():
    def inner():
        print(a)
    inner()
outer()
posted @ 2019-05-04 23:47  cjw1219  阅读(184)  评论(0编辑  收藏  举报