Python名称空间的概念 and 作用域应用

前言:

在内存中开辟的一块空间用于存放创建的变量,由于之前一直忽略了变量名的存储,但其实内存中还存在一块空间用于将变量名和内存地址进行绑定的空间,那么这个空间就叫做名称空间



名称空间(Namespaces)


内置命称空间


存放内置的名字,该名称空间伴随着解释器启动就产生了,内置空间存放了如:print、len、input等内置方法

生命周期:当解释器关闭时则销毁


全局名称空间


除了局部和内置,其它都是全局,全局需要自己定义,Python文件在执行以后才会产生全局名称空间

生命周期:文件运行完毕 全局名称才会销毁


局部名称空间


在容器(函数、类等)内定义的名字,局部空间也是需要自己定义的,调用容器时局部名称空间就会产生

生命周期:临时产生,调用结束时,局部名称就会销毁


名称空间加载的顺序


首先py文件是由python解释器打开的,在python解释器中内置名称空间在加载后,文件才会打开,文件打开后全局名称空间才会产生,那么局部名称空间只有在调用了容器以后才会产生。

所以加载循序:内置名称空间 > 全局名称空间 > 局部名称空间


名称空间的查找顺序


当前位置在局部

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

当前位置在全局

  • 全局名称空间 -> 内置名称空间

可以试想,如果没有名称空间将各个定义的名称进行划分,那么同样的名字,比如name就只能整个程序存在一个,但是有了名称空间的话可以在全局和局部定义相同名称都互不影响了。

Python之禅对名称空间的描述:
在这里插入图片描述
Namespaces are one honking great idea – let’s do more of those!
名称空间是一个非常好的主意——让我们做更多的工作吧!

作用域

作用域指定是:产生作用的范围


全局作用域

全局作用域:全局名称空间+内置名称空间,全局作用域的变量可以在任意范围内访问

# 全局作用域

x = 18

def func():
	print(x)	# 以及print这个内置名称都可以在局部内使用

func()

结果为:18

局部作用域

局部作用域:此作用域中的值只能在局部使用

x = 111 # 全局变量
def func1():
	print(x)	# 可以访问全局变量x,但是不能修改它
	# x += 20	# 报错:局部并没有定义x
	
	# 与全局变量名虽然相同,但是含义却不同
	x = 10	# 这个只能在这个局部内访问,与外界的x没有任何关联
	print(x)
func1()
打印结果:
10
20

错误使用

x = 111
def fun1():
    print(x)   # 先检测语法,发现函数内有局部变量,那么同时又发现这个x是先调用后定义,所以报错
    x = 111

fun1()

需要注意:作用域的关系在函数定义时就已经确定好,即检测语法时确定的,与函数调用位置无关,与函数定义的位置有关

实例

x = 20
def func():
	print(x)

x = 10

func()	# 猜测一下打印内容是什么?

'''

虽然定义时是x这个变量存在,因为函数是优先找全局变量,那么如果调用位置前没有
x=10 那么打印结果就是:20

但是此时,调用函数的位置上面定义了一个x=10 那么函数在被调用时找到就是x=10这个变量

'''

实例2:



x = 111
def func1():
    print(x)

def func2():
    x = 222
    func1() # 注意:在调用func1函数时,里面的内容已经定义好了,并不会受func2这个函数的影响

func2()

'''
主要是func1在定义阶段调用的是x这个全局变量,而func2里面x 与外面定义的x是两个变量
所以func2在调用func1的时候并不会影响到它 所以打印结果是111

总结:因为func1 调用的是全局变量,所以只有这个全局变量x在func1被调用前改变了,
那么最后的值就会是改变的那个

如下:

x = 333
func2()	

打印结果:333
'''

可以获取该函数的外层函数定义的变量

x = 1
def func1():
	x = 10	# 这个只能在这个局部内访问,与外界的x没有任何关联

	def func2():
		y = 20
		
		print(x)
		# 可以找到,因为局部找值是先在里面找,再向外一层一层找
		所以打印结果:10
		
		
	print(y)	# 报错:在func1 函数里无法找到func2的值
	
	func2()	# func1里面调用func2
	
func1()	# 调用func1

重点:外面不能找里面,但是里面可以找到外面


函数的global和nonlocal关键字


用于对不属于当前作用域的变量进行操作

global关键字

用于将全局变量导入到函数内容,导入后可以对其的值进行更改,并未改变它的作用域范围

x = 10
def func():
	# x += 20 错误操作,当前局部内没有此变量可供操作
	
	global x # 将全局变量中的x导入进来
	x += 10

print(x) # 未在函数内更改前

func()
print(x) # 在函数内更改后

打印结果:20

nonlocal关键字

只能用于将局部函数内的变量导入到其内部函数,并且是从当前函数向外层函数逐个查找,如果没有则报错

def func():
	x = 20
	print(x) # 未修改前
	打印结果:20
	def func2():
		# x += 20  错误操作:注意看当前这个函数内并没有x变量

		nonlocal x	# 将外层函数的x变量导入进来
		x += 10
		
	func2()	# 调用这个内部函数
	
	print(x) # 修改后
	打印结果:30

func()

注意:nonlocal 只能用于函数内,并且是从里向外查找是否有这个变量,有的话则导入,如果到了最外层的函数还没有,那么不会到全局去找,而是直接报错

x = 20
# 不会到这里来查找

def func():
		# 这里是否有??
    def func2():
    		# 这里是否有x?
        def func3():
        
            nonlocal x  # 不断向外层函数查找是否有这个变量

            print(x)	# 结果是报错:没有找到x
                
        func3()	# 调用func3这个内部函数

    func2()  # 调用这个func2这个内部函数

func()

注意:只能从当前向外查找,不能从外向里查找,切记切记!!

这部分知识点,你get到了吗!

技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点赞 收藏+关注 谢谢支持!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值