python中global、local、nonlocal及闭包的特殊使用补充

先看下下面的闭包函数热下身

def outer(x):
    def inner(y):
        nonlocal x    # 使用 nonlocal,使内部函数可以修改外部函数的变量。
        x = x + y
        return x + y

    return inner

fun = outer(10)

print(fun(10))   # 第一个 fun(10)
print(fun(10))   # 第二个 fun(10)
print(fun(10))   # 第三个 fun(10)

其运行结果为:

30
40
50

三个 fun(10) 的运行结果是不同的,分别为30,40,50。


为什么会这样呢?
这就是闭包的效果,它可以保持局部变量不被系统回收。

首先看第一个 fun(10) , 其相当于fun(10) = outer(10)(10)

def outer(10):           # 传入的 x = 10
    def inner(10):       # 传入的 y = 10
        nonlocal x       # 使用 nonlocal
        x = 10 + 10      # >>> 此时 x = 20 了
        return x + y     # 最后 return 20 + 10 = 30

    return inner

第一个 print(fun(10)) 运行结束后,变量 x = 20,且“储存”在 fun = outer(10) 中。
然后是第二个 print(fun(10))

def outer(x):           
    def inner(10):		 # 传入的y = 10
        nonlocal x       # 使用 nonlocal, 此时的 x 已是 20 了。
        x = 20 + 10      # >>> 此时 x = 30 了
        return x + y     # 最后 return 30 + 10 = 40

    return inner

同理,所以最后 第二个 print(fun(10)) 的输出结果就是 50 了。

闭包的这个功能可以实现既不通过更改全局变量的情况下,进行函数内部变量的传递。

现在看看 global 使用位置的不同,所产生的不同效果

1、不使用global

x = 0

def global_test():
    x = 10
    print(f'1外部函数中的x为:{x}')

    def inner():
        x = 100
        print(f'内部函数的x为:{x}')

    inner()
    print(f'2外部函数中的x为:{x}')

global_test()
print(f'全局变量x:{x}')

运行结果为:

1外部函数中的x为:10
内部函数的x为:100
2外部函数中的x为:10
全局变量x:0

说明:全局变量和局部变量互不影响,各自独立。

2、在外部函数中使用 global

x = 0

def global_test():
    global x
    x = 10
    print(f'1外部函数中的x为:{x}')

    def inner():
        x = 100
        print(f'内部函数的x为:{x}')
        
    inner()
    print(f'2外部函数中的x为:{x}')

global_test()
print(f'全局变量x:{x}')

运行结果为:

1外部函数中的x为:10
内部函数的x为:100
2外部函数中的x为:10
全局变量x:10

改变了全局变量,但内部函数中的变量对外部函数和全局变量都没影响。
说明:外部函数的 global 只影响全局变量,而对闭包中内部函数的变量没影响。

3、在闭包函数中使用 global

x = 0

def global_test():
    x = 10
    print(f'1外部函数中的x为:{x}')

    def inner():
        global x
        x = 100
        print(f'内部函数的x为:{x}')

    inner()
    print(f'2外部函数中的x为:{x}')

global_test()
print(f'全局变量x:{x}')

运行结果为:

1外部函数中的x为:10
内部函数的x为:100
2外部函数中的x为:10
全局变量x:100

闭包中内部函数的变量对外部函数没影响,但改变了全局变量。

4、在外部函数和内部函数中都使用 global

x = 0

def global_test():
    global x
    x = 10
    print(f'1外部函数中的x为:{x}')

    def inner():
        global x
        x = 100
        print(f'内部函数的x为:{x}')

    inner()
    print(f'2外部函数中的x为:{x}')


global_test()
print(f'全局变量x:{x}')

运行结果:

1外部函数中的x为:10
内部函数的x为:100
2外部函数中的x为:100
全局变量x:100

此时内部函数,外部函数,全局变量都已互相关联。只要有一个变动,都会互相影响了。
说明:对于 global 的使用位置,只影响其同层级函数的局部变量与全局变量之间的关联性。

待补充……

你可能感兴趣的:(python知识点整理,python,函数闭包)