名称空间与作用域

一、名称空间

定义:名称空间(namespace):存放名字的地方,是对栈区的划分。

有了名称空间之后,就可以在栈区中存放相同的名字,详细的,名称空间。

名称空间是各自独立的,没有包含关系

1.1、内置名称空间

存放的名字:存放的是解释器内置的名字

>>> print
<built-in function print>
>>> input
<built-in function input>

存活周期:python解释器启动则产生,python解释器关闭则销毁

1.2、全局名称空间

存放的名字:不是函数内部定义,也不是内置的,剩下的是全局名称空间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保失败,源站可能有防盗链机制,建议将图片保存下来直接上传存上传(imKXpdgSNzLI-1625063372035)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-202106301754990.png41)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210630164758390.png)]

x = 10 ,if判断都是全局名称空间

def func(): # func = 函数的内存地址,所以是全局内存空间
	a = 111 # a,b在函数内部定义,属于全局名称空间
	b = 222

存活周期:python文件执行产生则产生,python文件运行完毕后销毁

1.3、局部名称空间

存放的名字:在调用函数时,运行函数体代码过程中产生的函数内的名字

存活周期:在调用函数时存活,函数调用完毕后则销毁

1.4、名称空间的加载顺序

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

1.5、名称空间的销毁顺序

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

1.6、名字的查找优先级

当前所在的位置向上一层一层查找

如果当前在局部名称空间:局部名称空间–>全局名称空间–>内置名称空间

input = 333
def func():
	input= 444
	print(input)
func() # 打印结果 444

input = 333
def func():
	# input= 444 注释掉
	print(input)
func() # 打印结果 333

# input = 333 注释全局名称
def func():
	# input= 444
	print(input)
func() # 打印结果 <built-in function input>

如果当前在全局名称空间:全局名称空间–>内置名称空间

input = 333
def func():
	input= 444
func()
print(input) # 在全局,会从全局找 打印333

# input = 333 注释,全局没有,开始从内建找 
def func():
	input= 444
func()
print(input) # 在全局,而全局没有,开始从内建找 打印<built-in function input>

示例1:

x = 111
def func():
	print(x)
func() #打印 111

def func():
	print(x)
x = 111
func() # 111 
# 在运行 func()之前,x=111已经运行过,所以会打印出来

示例2:名称空间的“嵌套”关系(名称空间不存在嵌套关系,这里只是为了理解)

x = 1
def func(): 
	print(x)
def foo():
	x = 222
	func()
foo()  # 打印1 
#  没有打印 222 ,说明名称空间的嵌套关系是以函数定义阶段为准的(在函数定义时就已经确定),与调用位置无关。

示例3:函数嵌套定义

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4NxzTUVY-1625063372039)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210630203833323.png)]

input  = 111
def f1():
	input = 222
	def f2():
		input=333
		print(input)
	f2()
f1()  # 打印 333

input  = 111 # 这里注释,在内置名称空间找 打印<built-in function input>
def f1():
	input = 222 # 这里注释,会在全局里面找,打印111
	def f2():
		# input=333 注释
		print(input)
	f2()
f1()  # 打印 222 

示例4:

x = 111
def func():
	print(x) # 这里把x识别成了一个局部的东西,这是因为在扫描语法时,下面有一个x,确定x = 222 在局部名称空间,在定义阶段确定,而在调用时,发现x并未定义,应该将x放到print之前
	x = 222
func()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8VpF68aC-1625063372041)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210630204650126.png)]

二、作用域

作用域–>作用范围

2.1、全局作用域

全局作用域:内置名称空间,全局名称空间

特点:全局存活

​ 全局有效:被所有函数共享

# 不同的函数内的名字彼此都是独立的,但他们的全局是一直存在
x = 111
def foo():
	
	print(x,id(x))
def bar():
	
	print(x,id(x))
foo()
bar()
print(x,id(x))
111 2050010768
111 2050010768
111 2050010768
2.2、局部作用域

局部作用域:局部名称空间的名字

特点:临时存活,函数调用结束就死掉

​ 局部存活:函数内有效

三、LEGB

通过LEGB规则对变量名进行作用域解析

我们已经知道了多个命名空间可以独立存在,而且可以在不同的层次上包含相同的变量名。“作用域”定义了Python在哪一个层次上查找某个“变量名”对应的对象。接下来的问题就是:“Python在查找‘名称-对象’映射时,是按照什么顺序对命名空间的不同层次进行查找的?”

答案就是:使用的是LEGB规则,表示的是Local -> Enclosed -> Global -> Built-in,其中的箭头方向表示的是搜索顺序。

#b builing
#g global
def f1():
	#enclosing
	def f2():
		# enclosing
		def f3():
		# local
		pass

Local 可能是在一个函数或者类方法内部。
Enclosed 可能是嵌套函数内,比如说 一个函数包裹在另一个函数内部。
Global 代表的是执行脚本自身的最高层次。
Built-in 是Python为自身保留的特殊名称。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值