美文网首页
Python关键字:global和nonlocal

Python关键字:global和nonlocal

作者: 平仄_pingze | 来源:发表于2018-05-21 17:12 被阅读8次

    结论

    global和nonlocal在局部声明变量,表明变量的定义不在块内,而在全局/上级局部作用域内。

    global

    先谈一下Python的引用查找循序:
    先在当前局部作用域找声明,如果找不到,到上层(包括全局)找

    举一个例子:

    a = 1
    def foo():
        b = a
        return b
    
    print(foo())
    

    程序输出 1。foo()内部没有定义1,它向上层找到了全局变量a。

    稍微修改:

    a = 1
    def foo():
        b = a
        a = 2 # newline
        return b
    
    print(foo())
    

    程序报错:UnboundLocalError: local variable 'a' referenced before assignment
    因为这次a在foo()内部声明了,但使用先于声明,是错误的。

    再改一下:

    a = 1
    def foo():
        global a # newline
        b = a
        a = 2
        return b
    
    print(foo())
    

    正常输出1。global关键字声明,foo()中的a即是全局变量a,后面的都是赋值语句。

    nonlocal

    nonlocal的功能和global类似,只是nonlocal声明的变量在上级局部作用域内,而不是全局定义。
    上面的代码中,将global改为nonlocal:

    a = 1
    def foo():
        nonlocal a
        b = a
        a = 1
        return b
    print(foo())
    

    报错:SyntaxError: no binding for nonlocal 'a' found。表明nonlocal不能声明全局变量。

    将foo包裹在上层局部作用域中:

    def foo_upper():
        a = 1
        def foo():
            nonlocal a
            b = a
            a = 1
            return b
        print(foo())
    
    foo_upper()
    

    正常输出1

    nonlocal应用:闭包

    利用nonlocal可以实现Python的闭包。
    比如:

    def adder():
        num = 0
        def add():
            nonlocal num
            num += 1
            return num
        return add
    
    add = adder()
    print(add())
    print(add())
    print(add())
    print(add())
    

    打印出了:1 2 3 4

    或者,实现一个单例函数(不能同时执行多次)装饰器:

    def singlecase(fn):
        '装饰器:单例模式'
        running = False
        @functools.wraps(fn)
        def wrapper(*args, **kargs):
            nonlocal running
            if running:
                raise Exception('单例函数 ' + fn.__name__ + ' 已经在执行')
            running = True
            try:
                return fn(*args, **kargs)
            finally:
                running = False
        return wrapper
    

    相关文章

      网友评论

          本文标题:Python关键字:global和nonlocal

          本文链接:https://www.haomeiwen.com/subject/ckkqjftx.html