名称空间与作用域

blog 121 0

名称空间

名称空间就是存放名字的地方。假设a=10,那么Python就会去申请内存空间存放对象10,之后将a=10的绑定关系存放在名称空间中。名称空间是对栈区的一种划分,真正存在的是栈区,而名称空间则是一种虚拟的划分。

名称空间与作用域

内置名称空间和全局名称空间仅有一个,只有局部名称空间可以是多个。

内建名称空间

存放的名字:存放Python解释器内置的名字,比如print、open、input等等

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

名称空间与作用域

全局名称空间

存放的名字:只要不是函数内定义的名字也不是内建的名称,那么该名称就归属于全局名称空间。

存活周期:Python文件执行则产生,Python文件执行完毕之后则销毁。

import os # 模块名
x = 10  # 全局变量x
if x < 10:
	a = 20 # 全局变量a
	b = 30 # 全局变量b
	for i in range(1,20):
		print(i) # 全局变量i

 
def bar(): # 全局函数bar()
	pass


class Foo: # 全局类Foo
	pass 

局部名称空间

存放的名字:在调用函数的时候,函数内部代码体内产生的名字,归属于局部名称空间。

存活周期:函数调用时被创建,函数调用结束时被销毁。

名称空间的加载顺序

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

销毁顺序

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

名字的查找优先级

会在当前所在的层向上一层一层的往上找

# 如果当前在局部名乘客空间的话
# 局部名称空间>全局名称空间>内置名称空间
# 示范1:

def bar():
	print(x) # 123

x = 123 
bar()

首先定义一个bar()函数,里面打印变量x的值。定义的时候,是不会执行函数体代码的。只会检查语法是否有误,所以代码继续往下执行,发现了x=123,那么此时,x就被丢进了全局名称空间内,随后才调用了bar(),那么此时就会就会执行bar()函数体的东西,也就是打印变量x的值。Python在当前(局部)名称空间查找x,发现并没有被定义,于是就去它的上一层全局名称空间去找。发现x与123进行了绑定,则最后的结果输出了123

# 示例2:名称空间的嵌套关系,是以定义阶段为准的,而与调用阶段无关

y = 1 
def foo():
	print(y) # 1


def bar():
	y = 1000
	foo()

bar()
# 示例3:函数嵌套定义

input = 1
def f1():
	input = 23333
	def f2():
		input = 222222222
		print(input) # 222222222
	f2()

f1()
名称空间与作用域

如果当前名称空间(局部)的f2函数里没有input变量,我们则去f1函数里去找,如果f1函数里面也没有定义input我们则去全局名称空间去找。如果全局也没有的话,我们只能去内置名称空间去找。如果都没有找到则是"input" is notdefined

名称空间本身并无嵌套关系,画图只是我了易理解。

作用域

作用域就是作用范围的意思,其中分为全局作用域和局部作用域。

全局作用域

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

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

局部作用域

临时存活

局部有效:函数内有效

LEGB规则

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


print(input) # Built-in
# global
x = 10 
# enclosed
def f1():
	# enclosed
	def f2():
		# local
		def f3():
			pass

global和nonlocal

正常情况下,局部空间是不能修改全局名称值的,如果想要在局部名称空间中修改全局名称空间的值,则需要使用global关键字。

# 示例1:

a = 111
def wrapper():
	a = 23456

wrapper()
print(a) # 访问到是全局名称空间中的a  111

# 示例2: 如果想在局部名称空间中修改全局名称空间的值,则需要使用global

x = 10
def bar():
	global x
	x = 300
bar()
print(x) # 300
# nonlocal 修改函数的外层函数包含的名称

def f1():
	x = 21
	def f2():
		nonlocal x
		x = 4000
	f2()
	print(x) # 4000

f1()

发表评论 取消回复
表情 图片 链接 代码

分享