一:为何要有命名空间?python
两个函数求最大值,return函数的最大值,并将它打印出来了,那么能直接打印吗?看下面的函数函数
eg1:this
def max(x,y): z=x if x>y else y return z bigger=max(16,20) print(bigger)
打印结果:20内存
若是是这样呢?作用域
eg2:cmd
def max(x,y): z=x if x>y else y max(16,20) print(z)
打印结果:import
为何会报错?变量
由于咱们进行打印,打印的是全局变量,内部变量z没有被定义,全局变量不能引用内部变量。命名空间
也就是说:引用
从python解释器开始执行的时候,就在内存开辟出了一个空间。
没遇到一个变量就会把变量名和值的对应关系记录下来。
可是当遇到函数定义的时候,python解释器只是象征性的将函数关心读入内存(表示则这个函数已经存在,至于内部逻辑和变量解释器并不关心)
等到函数调用的时候,python解释器会在内存中再开辟一个内存来存储函数里面内容, 这个时候,才关注函数里面有哪些变量,而函数中的变量会存储在新开辟出来的内存中。函数中的变量只能在函数的内部使用,而且会随着函数执行完毕,这块内存中的全部内容也会被清空。
这个存放名字与值的关系的空间就是命名空间
代码从运行开始,建立的存储名字和值的关系空间就是全局命名空间,而在函数运行过程当中临时开辟空间就是局部命名空间。
二:命名空间的本质:存放名字与值的绑定关系
python之禅:
打开cmd命令在python解释器中输入import this
三:命名空间种类
内置命名空间 全局命名空间 局部命名空间
内置命名空间:存放python解释器提供的关键字:sum,print,str,list等50多种内置关键字。
四:三种命名空间的加载和取值顺序
加载顺序:
内置(程序运行前加载)----全局(程序运行中,从上到下加载)-----局部(程序运行中,调用才加载)
取值顺序:
在局部中:
局部--全局---局部(儿子能够花老子的钱,老子不能花儿子钱)
a=1 def max(): a=2 return a rr=max() print(rr) print(a)
打印结果:2,1
在全局:全局---局部
x = 1 def f(x): print(x) f(10) print(x)
打印结果:10,1
四:做用域
做用域就是做用范围,按照生效范围可分为全局做用域和局部做用域
全局做用域:包括全局命名空间和内置命名空间,整个文件任意位置被引用,全局生效。
局部做用域:只在局部命名空间内,局部范围有效。
globals和locals
def func(): a = 12 b = 20 print(locals()) print(globals()) func()
打印结果
global:声明函数在全局有效
a = 10 def func(): global a a = 20 print(a) print(a) func() print(a)
他的执行顺序
执行结果:
函数嵌套调用:
def max2(x,y): m = x if x>y else y return m def max4(a,b,c,d): res1 = max2(a,b) res2 = max2(res1,c) res3 = max2(res2,d) return res3 print(max4(23,-7,31,11)) print(max2(10,20))
显示结果:
函数的嵌套定义
eg1:
def f1(): print("in f1") def f2(): print("in f2") f2() f1()
eg2:
def f1(): def f2(): def f3(): print("in f3") print("in f2") f3() print("in f1") f2() f1()
函数的做用域链
def f1(): a = 1 def f2(): a = 2 f2() print('a in f1 : ',a) f1()
global适用于函数内部修改全局变量的值
nonlocal适用于嵌套函数中内部函数修改外部变量的值
def f1(): a = 1 def f2(): nonlocal a a = 2 f2() print('a in f1 : ',a) f1()
打印结果:2
'a in f1 : ',2