python global与nonlocal关键字

  1. 函数作用域
a = 1
print("函数outer调用之前全局变量a的内存地址: ", a , id(a))


def outer():
    a = 2
    print("函数outer调用之时闭包外部的变量a的内存地址: ", a,  id(a))

    def inner():
        a = 3
        print("函数inner调用之时闭包内部变量a的内存地址: ", a, id(a))

    inner()
    print("函数inner调用之后闭包外部的变量a的内存地址: ", a, id(a))


outer()
print("函数outer执行完毕,全局变量a的内存地址: ", a, id(a))
函数outer调用之前全局变量a的内存地址:  1 140704120484688
函数outer调用之时闭包外部的变量a的内存地址:  2 140704120484720
函数inner调用之时闭包内部变量a的内存地址:  3 140704120484752
函数inner调用之后闭包外部的变量a的内存地址:  2 140704120484720
函数outer执行完毕,全局变量a的内存地址:  1 140704120484688
  1. global 关键字
a = 1
print("函数outer调用之前全局变量a的内存地址: ",a , id(a))


def outer():
    a = 2
    print("函数outer调用之时闭包外部的变量a的内存地址: ", a,  id(a))

    def inner():
        global a #这里更改了!!!
        a = 3
        print("函数inner调用之时闭包内部变量a的内存地址: ", a, id(a))

    inner()
    print("函数inner调用之后闭包外部的变量a的内存地址: ", a, id(a))


outer()
print("函数outer执行完毕,全局变量a的内存地址: ", a, id(a))
函数outer调用之前全局变量a的内存地址:  1 140704120484688
函数outer调用之时闭包外部的变量a的内存地址:  2 140704120484720
函数inner调用之时闭包内部变量a的内存地址:  3 140704120484752
函数inner调用之后闭包外部的变量a的内存地址:  2 140704120484720
函数outer执行完毕,全局变量a的内存地址:  3 140704120484752

把inner函数内的a声明为global后,更改的是最外层的a,最外层a原来为1,更改后为3。

  1. nonlocal 关键字
a = 1
print("函数outer调用之前全局变量a的内存地址: ",a , id(a))


def outer():
    a = 2
    print("函数outer调用之时闭包外部的变量a的内存地址: ", a,  id(a))

    def inner():
        nonlocal a #这里又更改了
        a = 3
        print("函数inner调用之时闭包内部变量a的内存地址: ", a, id(a))

    inner()
    print("函数inner调用之后闭包外部的变量a的内存地址: ", a, id(a))


outer()
print("函数outer执行完毕,全局变量a的内存地址: ", a, id(a))
函数outer调用之前全局变量a的内存地址:  1 140704120484688
函数outer调用之时闭包外部的变量a的内存地址:  2 140704120484720
函数inner调用之时闭包内部变量a的内存地址:  3 140704120484752
函数inner调用之后闭包外部的变量a的内存地址:  3 140704120484752
函数outer执行完毕,全局变量a的内存地址:  1 140704120484688

nonlocal 关键字使inner函数中的a变为outer函数中的a,更改的是外边一层的a。

  1. 例题
a = 10
def test():
    a += 1
    print(a)
test()

结果: error

Python的规则是,如果在函数内部要修改一个变量,那么这个变量需要是内部变量,除非你用global声明了它是外部变量。很明显,我们没有在函数内部定义变量a,所以会弹出局部变量在未定义之前就引用的错误。

name ='jack'

def f1():
   print(name)

def f2():
   name = 'eric'
   f1()

f2()

结果: jack
f2中调用f1,我们要从f1的定义处寻找最近的name定义,是外部的jack。
Python函数的作用域取决于其函数代码块在整体代码中的位置,而不是调用时机的位置。

name = 'jack'

def f2():
    name = 'eric'
    return f1

def f1():
    print(name)

ret = f2()
ret()

结果:还是jack!!

你可能感兴趣的:(python global与nonlocal关键字)