名称空间 / 作用域
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