python之函数名称空间,作用域,嵌套函数

嵌套函数

定义

函数内部定义的函数,无法在函数外部使用内部定义的函数。

def f1():
    def f2():
        print('from f2')
    f2()

f2()  # NameError: name 'f2' is not defined


def f1():
    def f2():
        print('from f2')
    f2()

f1()

'''
from f2
'''

名称空间的三大类(只存变量名)

  1. 内置名称空间

    • 定义:python解释器自带的方法,如:int,float,len等。类似小整数池
    • 生命周期:在python解释器启动时,就开始生效。直到python解释器关闭
  2. 全局名称空间

    • 定义:除了内置和局部的名字之外,其余都存在全局名称空间。如下面的代码x,func,z

      x = 1
      
      
      def func():
      	pass
      
      
      if x > 11:
          z = 20000
      else:
          z = 555
      print(z)
      
      
    • 生命周期:在文件执行时生效,文件执行完后失效

  3. 局部名称空间

    • 定义:在函数内部的都叫局部,也就是说在函数内部定义的变量 就是局部变量。如下图的x ,f2等等

      def test_one():
          x = 1
      	def max_num():
              print("from max_num")
          max_num()
          
      test_one()
      
    • 生命周期:在调用函数时生效,当函数执行结束后失效

名称空间加载顺序

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

变量名的查找顺序为

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

作用域

  1. 全局作用域

    • 定义:全局有效,全局存活,包含内置名称空间和全局名称空间.如x,test_one

      x = 1
      
      def test_one():
          print(x)
      
      test_one()
      
  2. 局部作用域

    • 定义:局部有效,临时存储,只包含局部名称空间。如x

      def test_one()
      	x = 1
          print(x)
          
      test_one()
      
  • PS:当局部名称空间没有对应的变量时,系统会自动去全局名称空间查找。没有找到就会报错。

    # 第一种情况
    x = 1
    def one():
        print(x)
        
    def two():
        x = 10
        one()
    two()
    
    '''
    1
    '''
    
    # 第二种情况
    x = 1
    def one():
        x = 10
        print(x)
    
    def two():
        x = 5
        one()
    
    two()
    
    '''
    10
    '''
    
    
    
    '''
    	总结:
    		对于第一种情况,程序调用了two函数,在two函数中调用了one函数,而one函数中没有定义x变量,对于one函数而言,它属于局部名称空间,变量x既然没有定义,那么就直接去上一级找,因此x=1
    		对于第二种情况,one函数中定义了x变量,因此直接使用即可,所以x=10
    
    '''
    
  • 函数对象+作用域应用

  • 补充知识点

    • global关键字:修改全局作用域中的变量

      x = 1
      
      def f1():
          x = 2
      
          def f2():
              #         global x  # 修改全局
              x = 3
          f2()
      
      f1()
      print(x)
      
      '''
      1
      '''
      
      
      
      x = 1
      
      def f1():
          x = 2
      
          def f2():
              global x  # 修改全局
              x = 3
          f2()
      
      f1()
      print(x)
      
      '''
      3
      '''
      
    • nonlocal关键字

      x = 1
      
      def f1():
          x = 2
      
          def f2():
              #         nonlocal x
              x = 3
      
          f2()
          print(x)
      
      f1()
      
      '''
      2
      '''
      
      
      x = 1
      
      def f1():
          x = 2
      
          def f2():
              nonlocal x
              x = 3
      
          f2()
          print(x)
      
      f1()
      
      '''
      3
      '''
      
    • 注意

      • 在局部名称空间中想要修改全局的可变类型,不需要任何声明,可以直接修改

        lis = []
        
        def f1():
            lis.append(1)
        
        print(f"调用函数前: {lis}")
        f1()
        print(f"调用函数后: {lis}")
        
      • 在局部如果想要修改全局的不可变类型,需要借助global声明,声明为全局的变量,即可直接修改

原文地址:https://www.cnblogs.com/plf-Jack/p/10951730.html