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!!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容