第二十七篇 名称空间与作用域

第二十七篇 名称空间与作用域

函数内部的函数只能在函数内部调用,不能再函数外部调用,要想知道为什么,我们就需要了解名称空间和作用域

一、名称空间

名称空间(name spaces):在内存管理那一章节中,我们知道变量的创建其实就是在内存开辟了一个新的空间。但是变量名的存储之前一直没有提及,其实在内存中有一块内存存储着变量名与变量之间绑定关系的空间,这个空间叫做名称空间

1.内置名称空间

  • 1.内置名称空间:存放python解释器自带的名字,比如 int、float、len、strip
  • 2.生命周期:在python解释器启动时生效,在python解释器关闭时失效

2.全局名称空间

  • 1.定义:除了内置和局部的名字之外,其余都放在全局名称空间。如下面的a、f、l、i
  • 2.生命周期:在文件执行时生效,在文件执行结束后失效
a = 0

def f():
    pass

l = [2,'k']

if 2>1:
    if 0<1:
        i = 6

3.局部名称空间

  • 1.定义:用于存放函数调用期间函数体产生的名字。比如下面的f2
  • 2.生命周期:在文件执行时函数调用期间时生效,在函数执行结束后失效
def f():
    def f2():
        print('ha')
    f2
    
f()

4.加载顺序

  • 由于.py文件是由python解释器打开的,因此一定是在python解释器中的内置名称空间加载结束后,文件才开始打开,这个时候才会产生全局名称空间,但文件内有某一个函数被调用的时候,才会开始产生局部名称空间,因此名称空间的加载顺序为:内置名称空间---->全局名称空间---->局部名称空间

5.查找顺序

  • 由于名称空间是用来存放变量名与值之间的绑定关系的,所以但凡要查找名字,就必须从名称空间中的三者之一找,查找顺序是,从当前的所在位置开始查找,如果当前所在的位置为局部名称空间,则查找顺序为:局部名称空间---->全局名称空局---->内置名称空间(也就是从当前位置开始,只会往外找)

    x = 0
    y = 1
    
    def f():
        x = 66
        y = 233
        print(x,y)
    
    f()   # 66 233
      ```python

    x = 0

def f():
print(x)

x = 6
f() #6
```

二、作用域

  • 作用域就是作用的区域
  • ==只需要记住:全局变量和局部变量,可能名字一样,但是两者根本不是同一种==

1.全局作用域

  • 全局作用域:全局有效,全局存活,包含内置名称空间和全局名称空间
x = 6

def f():
    print(x)
    
f()    # 6

2.局部作用域

  • 局部作用域:局部有效,临时存储,只包含局部名称空间
def f1():
    def f2():
        def f3():
            print(x)
        x = 1
        f3()
    f2()
    
f1()      # 1

3.注意点

  • 作用域关系在函数定义阶段就固定死了,与函数的调用无关
x = 1

def f():   # 函数定义阶段
    print(x)   # 由于f()函数的局部作用域没有x,所以会先去全局找,此时x=1
    
def f2():
    x = 6   # 这个x只能在f2()函数的局部作用域起作用,对f()函数没有丝毫影响
    f()   
    
f2()    # 1

4.函数对象与作用域应用

def f():
    def f1():
        print('hah')
    return f1

a = f()   

def f2():
    a()
    
f2()      # hah

三、补充知识点(不推荐使用)

1.global关键字

  • 作用:修改全局作用域中的变量
x = 1

def f():
    x = 6
    def f2():
        x = 233
    f2()
    
f()
print(x)    # 在当前位置查找,所以是全局作用域的x=1
x = 1

def f():
    x = 6
    def f2():
        global x    # 可以将局部变量变为全局变量
        x = 233
    f2()
    
f()
print(x)    # 233

2.nonlocal关键字

  • 修改局部作用域中的变量
x = 1

def f():
    x = 6
    def f2():
        x = 233
    f2()
    print(x)
    
f()      # 6
x = 1

def f():
    x = 6
    def f2():
        nonlocal x     # 可以使内部函数变量在外部也能使用,但不能修改为全局变量
        x = 233
    f2()
    print(x)
    
f()      # 233

3.注意点

1.在局部想要修改全局的可变类型,不需要任何声明,可以直接修改

2.在局部想要修改全局的不可变类型,需要借助global声明,声明为全局变量

lis = []

def f():
    lis.append(1)

# 函数调用前
print(lis)    # []

# 函数调用后
f()
print(lis)     # [1]

猜你喜欢

转载自www.cnblogs.com/itboy-newking/p/10953501.html