【Python基础】名称空间和作用域

发布于:2024-06-12 ⋅ 阅读:(15) ⋅ 点赞:(0)

1.名称空间

        将栈区进行分类,这些分类就是名称空间

名称空间 存放什么名字 空间个数 何时创建&销毁
内置名称空间built-in Python解释器内置的名字 1个 Python解释器启动&解释器关闭

全局名称空间

global

Python文件内定义的类名,变量名,模块名,函数名等等,排除函数内部定义&内置的 多个 Python文件执行前&文件执行完

局部名称空间

local,enclosing

函数内部定义的名字(包含函数的参数) 多个 函数调用时&调用结束后

2.名称空间的加载顺序

    内置名称空间 >  全局名称空间 > 局部名称空间

3.为什么要有名称空间?

    栈区存在相同变量名的情况下,数据会被覆盖;如果划分空间,就不会产生冲突

4.名称的查找顺序?

  •  整体的名称空间优先级:局部名称空间   >  全局名称空间 >    内置名称空间 > NameError
  •  查找顺序判断:
    • 先判断当前名称是属于哪种名称空间
    • 根据所在名称空间开始查找,如没有则向外找
    • 注意:查找顺序是以定义阶段为基准的
      • 场景1:
        
        x = 10
        
        def func1():
        
            print(x)
        
        def func2():
        
            x = 20
        
            func1()
        
        func2()  # 10  在func2内调用func1,func1里面输出x时,func1内部找不到定义的x就去全局空间查找;x=10是先于x=20被定义的
        
        
        场景2:
        
            input = 10
        
            def func1():
                
                def func2():
                
                    print(input)
                func2()
        
                input = 20
        
            func1() # 报错NameError,原因是在func1定义内有局部变量input,所以会优先使用该局部变量,但是执行的时候因为变量定义在func2()后,故调用func2的时候查找不到input而报错

5.作用域

 在名称空间的基础上,按照作用域进行分类: 全局作用域,局部作用域

  • 全局作用域: 
    • 包括:内置名称空间,全局名称空间
    • 特点: 全局存活,全局有效
    • 场景1: 想要函数内部修改全局变量,需要在变量前定义global---针对不可变类型
      (注意:函数内部定义全局变量,就不可再传该参数了)
          
          a = 10
      
          def func():
              
              global a
              
              a = 5
              
              return a
      
          func()
      
          print(a)  # 5
  • 局部作用域:
    • 包括: 局部名称空间
    • 特点:临时存活,局部有效
    • 修改局部变量的值,使用nonlocal,该关键字只会作用在函数内
场景1: 函数内部的局部变量修改,不会影响全局变量

    a = 10

    def func(a):
    
        a *= 2

    func(a)

    print(a) # 10



场景2: 针对嵌套函数,想要修改enclosing变量,需要在变量前定义nonlocal----针对不可变类型

def func1():

    x = 10

    def func2():
    
        nonlocal x

        x = 20
    func2()

    print(x)  # 20

func1()


场景3: 嵌套函数无变量,则报错

    def func1():

        def func2():
            
            nonlocal x

            x = 30
        func2()
        print(x)


    func1() # SyntaxError,因为扫描func2定义的时候就去找x所在的空间,func1里面没有则不会再向外去查找,直接报错