名称空间 / 作用域

2021-08-12  本文已影响0人  慕知

一,名称空间

1)内置名称空间
print(len)
# <built-in function len>   # built-in内建




2)全局名称空间:存放的是顶级的名字
x=10

def foo(y):  # 函数名foo是属于全局名称空间
    print(y)   # 函数内的名字属于局部!!!!

# 不管有多少个if分支,其下面的变量都属于顶级,下面的z/zz/zzz都属于全局名称空间
if True:
    z=3
    if True:
        zz=33
        if True:
            zzz=333






3)局部名称空间:函数内的名字即局部名称空间,伴随函数的调用/结束而临时产生/回收,函数的形参、函数内定义的名字都会被存放于该名称空间中
def foo():
    x=3


二,作用域

1) 作用域与名字查找的优先级
# 作用域与名字查找的优先级
#局部  ==> 全局 ==》 内置



#例1)
x=10           # 全局作用域的名字x
def foo():
    x=20      # 局部许作用域的名字x
    print(x)     # 在局部找x

# 调用foo会优先从局部作用域开始找,如果局部作用域没有,再去全局作用域找
foo()
# 20




#例2)
x=10
def foo():
    x=99

foo()  # 不回返回任何值
print(x)    # 在全局空间找x,所以返回10
# 10

2) grobal / nolocal
例1:global使用: 声明函数内的变量名是全局空间的变量名

x=1
def foo():
    global x     #声明x为全局名称空间的名字
    x=22

print(x)
# 1
# 虽然声明了是全局空间的名字,但是并没有调用,则x的值仍然是1




#例2:
x=1
def foo():
    global x
    x=20

# 调用函数foo
foo()

# 再取x的值
print(x)
# 20
# 这个时候已经在函数内改变了全局空间x的值






#例3:当实参的值为可变类型,函数内对该值的操作直接改变原值
list_L=[1,2,3]
def foo(n):
    n.append(6)

# 调用列表为实参,直接改变了列表的值
foo(list_L)
print(list_L)
# [1, 2, 3, 6]






# 例4:noloacal使用:嵌套多层的函数,nolocal关键字会声明其变量名来自外部嵌套函数的作用域
def f1():
    x=2
    def f2():
        nonlocal x
        x=66
    f2()    #调用f2,修改f1作用域x名字的值
    print(x)  # 在f1作用域中查看x,已经改变了值

f1()
# 66



# 以上如果把f1中x=2注视掉,调用函数f1(),则会报错!!!!!于哪里如下:


nonlocal x会从当前函数的外层函数开始一层层去查找名字x,
若是一直到最外层函数都找不到,则会抛出异常!!!!

易错补充
x=1
def foo():
    print(x)
    x=3

foo()
# 会报错,没有定义
# 分析:
# 1)先检测语法,在函数内找到了x的值,没有错误;
# 2)调用函数的时候,先print(x) 发现没有定义,即报错



# 如果想要函数内的值,需要先定义
x=1
def foo():
    x=3
    print(x)

foo()
# 3


# 如果是想调用全局的x,如下
x=1
def foo():
    print(x)
    y=77

foo()
# 1

内置:B
全局:G
函数最外层:E(可能会有多层嵌套)
函数最里层:L


上一篇下一篇

猜你喜欢

热点阅读