Python变量作用域
 
 
作用域
 
- Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里定义的。
 - 变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。
 - 变量在作用域中查找的顺序是 L→E→G→B。
 
 
作用域的分类
 
- L(Local):最内层,包含局部变量,比如一个函数/方法内部。
 - E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
 - G(Global):当前脚本的最外层,比如当前模块的全局变量。
 - B(Built-in): 包含了内建的变量/关键字等,最后被搜索。
 
 
全局变量
 
- 声明在函数外侧的变量是全局变量,所有函数都可以访问。
 - 当全局变量是不可变时,在函数内部修改,需要函数内首行添加global,如果全局变量是可变的,在函数内部修改的时候可以不加global。
 - 只访问不修改时,不用加global,同名时,局部变量会屏蔽全局变量。
 
 
m = 10
def test(x, y):
    global m        
    m += 88; x += 10;y += 10       
    print("inside function m:{}, x:{}, y:{}".format(m, x, y))
    return x + y+100
a, b, x, y = 1, 2, 66, 88
test(a, b)
print("outside function m:{}, x:{}, y:{}".format(m,x,y))
result:
inside function m:98, x:11, y:12
outside function m:98, x:66, y:88
 
m = [1,2,3]
a, b, x, y = 1, 2, 66, 88
def test(x, y):
    m.append(8); x += 10;y += 10       
    print("inside function m:{}, x:{}, y:{}".format(m, x, y))
    return x + y + 100
test(a, b)
print("outside function m:{}, x:{}, y:{}".format(m,x,y))
result:
inside function m:[1, 2, 3, 8], x:11, y:12
outside function m:[1, 2, 3, 8], x:66, y:88
 
局部变量
 
- 函数内部声明的变量,只能在函数内部使用,出了函数不能使用。
 - 当局部变量与全局变量重名时,优先局部变量。
 - 函数内部的变量可以随便修改,但是要在内部修改不可变全局变量,必须在函数首行声明global。不更改时,不需要声明。
 - 在嵌套内部函数中改变外部不可变对象, 需要加nonlocal。
 
 
m = 10
list1 = [1, 2, 3]
def foo():
    global m
    n = 0
    list2 = [4, 5, 6]
    m += 100
    def bar():
        global m    
        nonlocal n  
        m += 20
        n += 4
        list1.append(66)
        list2.append(88)
        print(m, n, list1, list2)
    bar()
    print(m, n, list1, list2)
foo()
print(m, list1)
result:
130 4 [1, 2, 3, 66] [4, 5, 6, 88]
130 4 [1, 2, 3, 66] [4, 5, 6, 88]
130 [1, 2, 3, 66]
 
变量查找顺序
 
- 在变量访问时,先查找本地变量,然后是嵌套此函数外部的函数体内的变量,之后是全局变量,最后是内建变量。