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():查看当前作用域中的变量

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

  • 相关阅读:
    Android 富文本框实现 RichEditText
    mmap和普通文件读写的区别和比较 & mmap的注意点
    exit和_exit的区别
    绑定线程到特定CPU处理器
    软中断与硬中断 & 中断抢占 中断嵌套
    线程与信号处理
    内核信号处理 & CPU8个通用寄存器
    SIGSEGV 和 SIGBUS & gdb看汇编
    Linux内核态用户态相关知识 & 相互通信
    Linux进程空间分布 & 上下文
  • 原文地址:https://www.cnblogs.com/xiayuhao/p/9461018.html
Copyright © 2011-2022 走看看