美文网首页
闭包中的nonlocal和global以及不使用nonlocal

闭包中的nonlocal和global以及不使用nonlocal

作者: Elvis_zhou | 来源:发表于2018-11-01 12:11 被阅读0次

    effective-python中,在阐述作用域变量时提到了nonlocal和global,当提到python2没有nonlocal时,实现了其功能,这例子没读懂:

    # Python2
    def sort_priority(values, group):
        found = [False]
        def helper(x):
            if x in group:
                found[0] = True
                return (0, x)
            return (1, x)
    
        values.sort(key=helper)
        return found[0]
    

    重中之重:基础,赶紧查查资料:

    1. 全局变量与局部变量

    全局变量为定义在函数外部的变量
    局部变量为定义在函数内部的变量

    2. 定义

    golobal 指定全局变量
    nonlocal 指定上一级变量

    3. 特性

    参考链接:https://www.cnblogs.com/echoboy/p/8973266.html

    4. 注意点:

    global是作用在全局的,并不能修改函数内的变量!

    found = 9
    
    
    def line_conf():
        found = "nihao"
    
        def line():
            # nonlocal found
            global found
            found = "hello"
            print('found1:', found, id(found))
    
        line()
        print('found2:', found, id(found))
    
    print('found0:', found, id(found))
    line_conf()
    print('found3:', found, id(found))
    
    ### 打开global:###
    found0: 9 10919680
    found1: hello 139819150299184
    found2: nihao 139819150391592
    found3: hello 139819150299184
    
    ### 打开nonlocal:###
    found0: 9 10919680
    found1: hello 140527291113520
    found2: hello 140527291113520
    found3: 9 10919680
    

    这个栗子很好的体现了global和nonlocal的作用范围,更体现了一点:当被global和nonlocal定义之后,变量的值是直接修改的。

    在闭包中,内嵌函数是可以读上层变量,但是不可写的:

    def line_conf():
        found = 6
    
        def line():
            # found = 8
            print('found1:', found, id(found))
    
        line()
        print('found2:', found, id(found))
    
    line_conf()
    
    ###  found = 8 注释了 ###
    found1: 6 10919584
    found2: 6 10919584
    
    ###  打开 found = 8  ###
    found1: 8 10919648
    found2: 6 10919584
    
    

    读到这里,之前的疑惑就可以解开了:
    为什么可以用list起到nonlocal的作用?
    因为found变量在内层函数是不可以写上一层的,但是可以读(因为没修改id),所以我们把found设置成列表,让解释器去上一层读取这个列表(也就是说只要在不改变id的前提下就可以拿到上层的变量),注意!上面的栗子证明,nonlocal和global都是直接修改变量的(也就是id),列表的修改是不改变id的,所以,在这里使用列表也可以达到nonlocal的效果。

     Python2
    def sort_priority(values, group):
        found = [False]
        def helper(x):
            if x in group:
                found[0] = True
                return (0, x)
            return (1, x)
    
        values.sort(key=helper)
        return found[0]
    
    print('Found:', sort_priority(values, group))
    print(values)
    
    ###       ###
    Found: True
    [7, 9, 1, 2, 3, 4, 5, 6, 8]
    

    相关文章

      网友评论

          本文标题:闭包中的nonlocal和global以及不使用nonlocal

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