zoukankan      html  css  js  c++  java
  • python中的作用域与名称空间

    python中的名称空间以及作用域分析

    从Python解释器开始执行之后,就在内存中开辟一个空间,每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读入内存,表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。等执行到函数调用的时候,Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量会储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。

    名称空间:存放名字与内存地址关系的一个空间

    全局名称空间:在python代码运行时就创建的变量名与内存地址对应关系的空间

    局部名称空间:函数或类在运行时临时开辟出来的内存空间

    作用域:作用域就是能够起作用的范围(如变量名被引用)

    在python中,作用域分为全局作用域局部作用域

    全局作用域:包含内置名称空间以及全局名称空间,在python文件中任意位置都能被引用,全局有效。

    局部作用域:局部名称空间,只在局部有效,如函数,类等

    作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关

    名称空间的加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

    名称空间的取值顺序:局部命名空间->全局命名空间->内置命名空间

    global:

    声明一个全局变量。
    在局部作用域中想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)。
    
    def func():
        global a  #没有则创建一个全局变量
        a = 3
    func()
    print(a)  #3
    
    
    count = 1
    def search():
        global count
        count = 2
    search()
    print(count)  #2
    
    def foo():
        a = 1
        def bar():
            global a
            print(a)
        bar()
    foo()  #报错  name 'a' is not defined
    #这是由于foo中的a不是全局作用域中的变量,那么在bar中重新创建了一个全局变量a,但是没有给a赋值,所以爆出这个错误
    
    #对可变数据类型(list,dict,set)可以直接引用不用通过global,但是不能对改变它的内存地址,可以增加、删除,但`l1=l1[1:3]`时,这样就修改了原来的内存地址,所以会报错。
    li = [1,2,3]
    dic = {'a':'b'}
    
    def change():
        li.append('a')
        dic['q'] = 'g'
        print(dic)
        print(li)
    change()
    print(li)
    print(dic)
            
    

    nonlocal:

    不能修改全局变量。
    在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。
    
    def add_b():
        b = 42
        def do_global():
            b = 10
            print(b)    #10 --------->1
            def dd_nonlocal():
                nonlocal b
                b = b + 20
                print(b)  #30
            dd_nonlocal()
            print(b)  #30 -------------2
        do_global()
        print(b)  #42
    add_b()
    #由于dd_nonlocal中声明的变量是从do_global中引用来的,所以在函数do_global中以及里面嵌套的函数中,都是相同的变量b,同时代码是从上到下执行,所以1出的b还没改变,还是10,但是2处的b已经改变了
    
    a = 1
    def foo():
        print(a)
        def bar():
            nonlocal a
            print(a)
        bar()
    foo()  #SyntaxError: no binding for nonlocal 'a' found
    #报错是由于nonlocal只能定义局部变量,此时的a是全局变量,所以报错
    

    globals():查看全局作用域中的变量

    locals():查看当前作用域中的变量

    同时需要注意,在局部作用域中只能对全局变量进行引用,但是不能修改,这个修改只指的是不能对被引用的变量的内存地址进行改变,

  • 相关阅读:
    vue自定义指令
    ZOJ Problem Set–2104 Let the Balloon Rise
    ZOJ Problem Set 3202 Secondprice Auction
    ZOJ Problem Set–1879 Jolly Jumpers
    ZOJ Problem Set–2405 Specialized FourDigit Numbers
    ZOJ Problem Set–1874 Primary Arithmetic
    ZOJ Problem Set–1970 All in All
    ZOJ Problem Set–1828 Fibonacci Numbers
    要怎么样调整状态呢
    ZOJ Problem Set–1951 Goldbach's Conjecture
  • 原文地址:https://www.cnblogs.com/xiayuhao/p/9461018.html
Copyright © 2011-2022 走看看