定州社区,你这个大胖子,压铆螺母
【目录】
一、名称空间
1. 内置名称空间
2. 全局名称空间
3. 局部名称空间
二、作用域
1. 全局作用域与局部作用域
2. 作用域与名字查找的优先级
l —— local(function);函数内的名字空间
e —— enclosing function locals;外部嵌套函数的名字空间(例如closure)
g —— global(module);函数定义所在模块(文件)的名字空间
b —— builtin(python);python内置模块的名字空间
# builtin b —— builtin(python);python内置模块的名字空间 # global g —— global(module);函数定义所在模块(文件)的名字空间 def f1(): # enclosing e —— enclosing function locals;外部嵌套函数的名字空间(例如closure) def f2(): # enclosing e —— enclosing function locals;外部嵌套函数的名字空间(例如closure) def f3(): # local l —— local(function);函数内的名字空间 pass
# 在python解释器内: ''' >>> print <built-in function print> >>> input <built-in function input> '''
即 伴随python文件的开始执行/执行完毕而产生/回收,是第二个被加载的名称空间,文件执行过程中产生的名字都会存放于该名称空间中,如下名字:
import sys #模块名sys x=1 #变量名x if x == 1: y=2 #变量名y def foo(x): #函数名foo y=1 def bar(): pass class bar: #类名bar pass
if c==0: x=2 #if 为顶级代码,且不是函数,x为全局命名空间的名字 print(x)
def func(a,b): pass func(10,1) func(11,12) func(13,14) func(15,16)
def foo(x): y=3 #调用函数时,才会执行函数代码,名字x和y都存放于该函数的局部名称空间中
# input=333 #全局作用域的名字input def func(): input=444 # 局部名字input print(input) #在局部找input func() 输出结果: 444
input=333 #全局作用域的名字input def func(): # input=444 #局部没有名字input,则找 全局作用域的名字input print(input) func()
输出结果: 333
input=333 #全局变量
def func(): input=444 #在函数调用时产生局部作用域的名字input
func()
print(input) # 该语句不属于函数体,属于全局命名空间;函数调用时,对该语句没有影响,所以直接执行打印功能,从全局命名空间开始找,即输出全局变量 input=333 输出结果: 333
# input=333
def func(): input=444 func()
print(input) # 该语句不属于函数体,属于全局命名空间;函数调用时,对该语句没有影响,所以直接执行打印功能,从全局命名空间开始找,
全局空间没有值,则在内置命名空间找,即 <built-in function input> 输出结果: <built-in function input>
def func(): print(x) x=111 # 全局变量 func()
x=1 def func(): print(x) def foo(): x=222 func() foo()
def f2(): input = 333 print(input) input = 222 # 是全局变量,函数f2调用时先在函数内的局部空间找值,有局部变量input = 333,故打印该值。 f2() 输出结果: 333
input=111 def f1(): def f2(): input=333 print(input) input=222 f2() f1() # f1嵌套子函数f2,子函数f2即为f1的函数体,所以函数调用执行过程同上 输出结果: 333
input=111 def f1(): def f2(): # input=333 #将局部变量注释,则f2执行时,在函数的局部空间内找不到值,会在其上一层的函数空间找,存在全局变量 input=222,执行f2,输出结果 222 print(input) input=222 f2() f1() 输出结果: 222
input=111 def f1(): def f2(): # input=333 print(input) # input=222 #若将f2的局部空间和最接近的全局空间的变量都去除,则函数f2执行时,会继续往下一个全局空间找值,存在input=111,则输出结果 111 f2() f1() 输出结果: 111
x=111 def func(): print(x) x=222 func() # unboundlocalerror: local variable 'x' referenced before assignment # 即 变量x在使用前并未定义
x=111 def func(): x = 222 print(x) func() 输出结果: 222
全局作用域:位于全局名称空间、内建名称空间中的名字属于全局范围
1、全局存活(除非被删除,否则在整个文件执行过程中存活)
2、全局有效: 被所有函数共享(在任意位置都可以使用)
x=111 #全局变量,全局有效 def foo(): print(x,id(x)) def bar(): print(x,id(x)) foo() bar() print(x,id(x)) 输出结果: 111 140730714743904 111 140730714743904 111 140730714743904
局部作用域: 位于局部名称空间中的名字属于局部范围
1、临时存活:即在函数调用时临时生成,函数调用结束后就释放
2、局部有效: 只能在函数内使用
x=100 #全局作用域的名字x def foo(): x=300 #局部作用域的名字x print(x) #在局部找x foo()#结果为300
(可先参照第一部分内容中的——6、名字查找的优先级)
先确定哪里有‘调用’操作,以此为起点,先不进行函数调用执行,而是以此为分水岭,开始名字查找——
确定当前位置,从当前位置开始查找,若无,则继续向上一层一层地往上查找。
总结如下:
(1)在局部作用域查找名字时,起始位置是局部作用域,所以先查找局部名称空间,没有找到,再去全局作用域查找:先查找全局名称空间,没有找到,再查找内置名称空间,最后都没有找到就会抛出异常
(2)在全局作用域查找名字时,起始位置便是全局作用域,所以先查找全局名称空间,没有找到,再查找内置名称空间,最后都没有找到就会抛出异常
(3)提示:可以调用内建函数locals()和globals()来分别查看局部作用域和全局作用域的名字,查看的结果都是字典格式。
在全局作用域查看到的locals()的结果等于globals()
(4)python支持函数的嵌套定义,在内嵌的函数内查找名字时,会优先查找自己局部作用域的名字,然后由内而外一层层查找外部嵌套函数定义的作用域,没有找到,则查找全局作用域 (栗子4号)
x=111 def func(): x=222 func() print(x) # 处于全局空间,所以先从全局空间找,存在x=111,输出结果 111
x=111 def func(): global x # 声明x这个名字是全局的名字,不要再造新的名字了 x=222 func() print(x) 输出结果: 222
l=[111,222] def func(): l.append(333) #l为可变类型,只是增减容器内的值,则没有必要声明为global func() print(l) 输出结果: [111, 222, 333]
l=[111,222] def func(): global l
l=123 #l为可变类型,要修改它的值,则一定要声明为global,才可修改 func() print(l) 输出结果: [111, 222, 333]
x=1 def outer(): x=2 def inner(): # 函数名inner属于outer这一层作用域的名字 x=3 print('inner x:%s' %x) inner() print('outer x:%s' %x) outer() #结果为 inner x:3 outer x:2
x=0 def f1(): x=11 def f2(): x=22 f2() print('f1内的x:',x) f1() #执行函数f1,先在函数体内的局部空间找值,存在x=11,则输出;内置函数f2里的x=22,只对f2有用。 输出结果: f1内的x: 11
x=0 def f1(): x=11 def f2(): nonlocal x #声明 内置函数f2里的x=22,不是内置函数f2里的局部变量,则归属于外层函数f2,x=22会覆盖掉x=11,作为最后的结果输出。 x=22 f2() #调用f2(),修改f1作用域中名字x的值 print('f1内的x:',x) #在f1作用域查看x f1() 输出结果: f1内的x: 22
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Python爬虫:Request Payload和Form Data的简单区别说明
浅谈Python中threading join和setDaemon用法及区别说明
Python3-异步进程回调函数(callback())介绍
python继承threading.Thread实现有返回值的子类实例
Python中使用threading.Event协调线程的运行详解
网友评论