python变量和作用域

python中的作用域分4种情况:

L:local,局部作用域,即函数中定义的变量;
E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
G:globa,全局变量,就是模块级别定义的变量;

B:built-in,系统固定模块里面的变量,比如int, bytearray等。

搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。

x = int(2.9)  # int built-in 
g_count = 0 # global def outer(): o_count = 1 # enclosing def inner(): i_count = 2 # local

变量的性质根据修改的顺序先来后到排序,如下两个例子:

A:
count = 10 def outer(): print(count) #输出10 outer()
B:
count = 10
def outer():
    count = 100
    print(count) #输出100
outer()
print(count)#输出10

A代码中count属于外部作用域中的变量,如果在outer中直接调用,那么默认调用的就是外部作用域中的count,因此A代码的输出为10.

B代码中outer函数试图修改count值,因为一个不在局部作用域里的变量默认只读,所以无法修改,因此Python会在当前的局部作用域内创建一个新的变量,该变量与外部的count同名,但是并非同一变量,所以在局部作用域内输出100,而在外部作用域内输出10.  

C:
count = 10 def outer(): global count count = 100 print(count)#输出100 outer() print(count)#输出100

A,B代码都无法实现修改外部作用域的变量值的目的,因此我们引入了global关键字,如C代码所示,用关键字global声明count之后,那么count的作用域就不只是局部,而是全局作用域,因此在outer中修改count,外部的count值也变化了,两次都打印了100.

C代码中的global关键字只对所有函数外层的变量起作用,即全局作用域,但是如果想对嵌套作用域中的变量进行修改,就需要nonlocal关键字,如D代码所示:

count=200
def outer():
    count = 10
    def inner():
        nonlocal count
        count = 20
        print(count)#输出20
    inner()
    print(count)#输出20
outer()
print(count)#输出200

inner函数中的count被nonlocal声明后,值被修改为20,因此嵌套作用域的count值也被修改为20,但是全局作用域的count并未被修改,仍然为200。 

x=100#全局变量
def f1(x):
    k=200#闭包变量
    def f2():
        nonlocal k#声明闭包作用域
        global x#声明全局作用域
        x*=x,这里只改变了global和local作用域的值,并未改变f1作用域的值
        k*=k
        print('k1' + str(k))#输出40000
        print('x1' + str(x))#输出10000
    f2()
    print('k2' + str(k))#输出40000
    print('x2' + str(x))#输出100,这里还是f1作用域,所以x的值未变
f1(x)
print('x3' + str(x))#输出10000

  

  

  

  

posted on 2017-05-30 23:55  vonkimi  阅读(160)  评论(0编辑  收藏  举报

导航