python——作用域

命名空间名称与对象之间的关系,可以将命名空间看作是字典,其中键:名称,值:对像;

注意:命名空间不共享名称。

当有多个命名空间时,可以按照既定的名称解析规则,来解析名称。按照定义的搜索顺序,在多个命名 空间中查找名称;

知识点一:

在python中的变量名,在第一次赋值时,将被创建,而且变量名只有被创建了,才能使用,否则会报错

知识点二:

在python中,只有模块,函数,类才可以引入新的作用域,其它代码不会引入新的作用域;

知识点三:

每一个模块都可以看做是一个全局作用域,python中是没有类似c++中可以存活整个项目的作用域;

python中作用域仅限于单个模块;

知识点四:

被正确赋值的变量除非声明为global,否则均为本地变量;“变量名只有被赋值才可以被声明为本地变量”;


变量名解析规则LEGB(Local , Inclosing, Global , Built_In )

L:局部的

E:封闭的

G:全局的

B:内置的

L ---->E------>G------->B;

也可以理解为:变量名分三个作用域进行查找:本地==>函数内==》全局===》内置


代码理解:

if 语句并未引入新的局部作用域 , 变量i 仍然在全局作用域中,故对print可见;

>>> if True:                       
	i = 4
>>> print i
4
>>>

调用函数fun1():

>>> def fun1():
	i = 12
	print i
	
>>> fun1()
12
>>> 
声明变量i , 且i被赋值为12,则其被创建在函数命名空间,即局部命名空间。执行fun()时,会在本地(函数内部)查找i(局部变量)。

调用函数fun2():

>>> i = 34
>>> def fun2():
	i = i + 1
	print i
	
>>> fun2()

Traceback (most recent call last):
  File "<pyshell#300>", line 1, in <module>
    fun2()
  File "<pyshell#299>", line 2, in fun2
    i = i + 1
UnboundLocalError: local variable 'i' referenced before assignment
>>> 
首先在定义fun2()之前,定义全局变量(global)i = 34 ,然后定义fun2(),同样在局部命名空间函数内,定义了局部变量i ;

但是在执行fun2()后出现:

UnboundLocalError: local variable 'i' referenced before assignment
错误。

所以即使定义了同名的全局变量,但是函数fun2()并未如预期的那样,现在局部命名空间查找变量,未找到再到全局命名空间查找;

python提出如下假设,如果在函数体内的任何地方对变量赋值,则python将名称添加到局部命名空间中。语句i=i+1对对象i进行赋值。

python假设无论在何处发生赋值,i都是函数func局部命名空间的一部分。当python尝试把1跟i相加时,该i名称在局部命名空间中,但它没有关联值,所以python报错。
问题出现在python何时决定使i出现在局部命名空间中。

实际i出现在局部命名空间中发生在代码运行前,即,在python运行到函数定义之前。由于创建命名空间时,python会检查代码并填充局部命名空间。在python运行那行代码之前,就发现了对i的赋值,并把它添加到局部命名空间中,当函数执行时,python解释器认为i在局部命名空间中但没有值,所以会产生错误。

调用函数fun3():

>>> i = 45
>>> def fun3():
	i = 23
	print i
>>> print i
45
>>> fun3()
23
>>> 
print i -->45:在本地(全局作用域)查找变量i,找到输出;

fun3()-->23:在本地命名空间找到变量i,输出;

调用fun4():

>>> i = 123
>>> def fun4():
	print i
>>> fun4()
123
>>> 
函数fun4():并未出现fun2()中的问题,因为函数内并没有进行赋值创建,fun2()内定义了局部变量i,但是其没有被赋值,或者说赋值对象(准确值)不存在;

fun4()内执行print i;局部查找i并未找到------>在全局命名空间找到同名i,且i = 123;输出;


调用函数fun5():

>>> def fun5():
	print j

>>> fun5()

Traceback (most recent call last):
  File "<pyshell#321>", line 1, in <module>
    fun5()
  File "<pyshell#320>", line 2, in fun5
    print j
NameError: global name 'j' is not defined
>>>

运行结构显示:global name ' j' is not defined

python首先在函数fun5() 的本地作用域查找变量j ,查找失败;继续道全局作用域和内置作用域中查找仍然失败;最终抛出NameError;


通过global将变量声明为全局域变量:

>>> var = 2324
>>> def fun6():
	global var
	print var
	var = var + 45
	print var
	
>>> print var
2324                          #全局var
>>> fun6()
2324                          #通过global ,声明为全局变量域2324
2369                          #对全局var + 45 
>>> 
除了通过global对全局变量进行访问外,还可以在函数中引用自身module,然后通过模块名.变量名的方式访问全局变量

thismodule.py

var = 99

def local():
    var = 0
    print var           #local var

def globl():
    global var         #global var
    var += 1
    print var          #global

def globl2():
    var = 0
    import thismod
    thismod.var += 2        #global var
    print var               #local var 


def globl3():
    var = 0
    import sys
    glob = sys.modules['thismod']
    glob.var += 3              #global var += 3
    print var                  # local var = 0
执行thismodule.py

>>> ================================ RESTART ================================
>>> import thismodule
>>> thismodule.val
100                                   #全局
>>> thismodule.local()
0                                     #局部
>>> thismodule.globl()
101                                   #全局
>>> thismodule.val
101                                   #全局
>>> thismodule.globl2()
23                                    #局部
>>> thismodule.val
103                                   #全局
>>> thismodule.globl3()
0                                     #局部
>>> thismodule.val                   
106                                   #全局
>>> 










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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值