标签:其他 依赖倒置原则 返回值 并且 container global 修改 cell 存储
在python解释器开始执行之后, 就会在内存中开辟一个空间, 每当遇到一个变量的时候, 就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表示这个函数存在了, 至于函数内部的变量和逻辑, 解释器是不关心的. 也就是说一开始的时候函数只是加载进来, 仅此而已, 只有当函数被调用和访问的时候, 解释器才会根据函数内部声明的变量来进行开辟变量的内部空间. 随着函数执行完毕, 这些函数内部变量占用的空间也会随着函数执行完毕而被清空。
我们首先回忆一下Python代码运行的时候遇到函数是怎么做的,从Python解释器开始执行之后,就在内存中开辟里一个空间,每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读如内存,表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。等执行到函数调用的时候,Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量回储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。
我们给这个‘存放名字与值的关系’的空间起了一个名字-------命名空间。
代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;
在函数的运行中开辟的临时的空间叫做局部命名空间也叫做临时名称空间。
现在我们知道了,py文件中,存放变量与值的关系的一个空间叫做全局名称空间,而当执行一个函数时,内存中会临时开辟一个空间,临时存放函数中的变量与值的关系,这个叫做临时名称空间,或者局部名称空间。
其实python还有一个空间叫做内置名称空间:内置名称空间存放的就是一些内置函数等拿来即用的特殊的变量:input,print,list等等
内置命名空间
就是python解释器一启动就可以使用的名字存储在内置命名空间中
内置的名字在启动解释器的时候被加载进内存里
全局命名空间---我们写的代码但不是函数中的代码
局部命名空间
所谓的加载顺序,就是这三个空间加载到内存的先后顺序,也就是这个三个空间在内存中创建的先后顺序,你想想他们能是同时创建么?肯定不是的,那么谁先谁后呢?我们捋顺一下:在启动python解释器之后,即使没有创建任何的变量或者函数,还是会有一些函数直接可以用的比如abs(-1),max(1,3)等等,在启动Python解释器的时候,就已经导入到内存当中供我们使用,所以肯定是先加载内置名称空间,然后就开始从文件的最上面向下一行一行执行,此时如果遇到了初始化变量,就会创建全局名称空间,将这些对应关系存放进去,然后遇到了函数执行时,在内存中临时开辟一个空间,加载函数中的一些变量等等。所以这三个空间的加载顺序为:内置命名空间(程序运行伊始加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载。
取值顺序就是引用一个变量,先从哪一个空间开始引用。这个有一个关键点:从哪个空间开始引用这个变量。
所以空间的取值顺序与加载顺序是相反的,取值顺序满足的就近原则,从小范围到大范围一层一层的逐步引用。
全局作用域>作用在全局>内置和全局名字空间中的名字都属于全局作用域 globals()
局部作用域>作用在局部>函数(局部名字空间中的名字属于局部作用域)locals()
对于不可变数据类型,在局部可以查看全局作用域中的变量
但是不能直接修改
如果想要修改,需要在程序的一开始添加global声明
如果在一个函数内声明了一个global变量,那么这个变量在局部的所有的操作将对全局变量有效。
函数名就是一个变量,具有变量的功能。可以被赋值;但是作为函数名它也有特殊的功能就是加上()就会执行对应的函数,所以我们可以把函数名当作一个特殊的变量。
def f1():
pass
print(f1) #<function f1 at 0x0000021198E7BB70>
函数名可以赋值给其他变量
def f1():
print(‘666‘)
a = f1 #把函数名当成一个变量赋值给另外一个变量
a() #函数调用f1()
#通过变量的赋值,变量a 和变量f1都指向这个函数的内存地址,那么a() 当然可以执行这个函数了。
函数名也可以当作容器类的元素
a = ‘jim‘
b= ‘bob‘
c = ‘ajian‘
l = [a,b,c]
for i in l:
print(i) # jim bob ajian
def func1():
print(‘1‘)
def func2():
print(‘2‘)
def func3():
print(‘3‘)
l = [func1,func2,func3]
for i in l:
i()
函数名可以当作函数的参数
def f1():
print(1)
def f2(f):
print(2)
f()
f2(f1)
函数名作为函数的返回值
def f1():
print(1)
def f2(f):
print(2)
return f
ret = f2(f1)
ret()
嵌套的函数,内部函数调用外部函数的变量
def f1():
s = ‘1234‘
def f2():
print(len(s))
return f2 #返回函数的名字
res = f1()
res()
判断闭包函数的方法 closure
#输出的__closure__有cell元素 :是闭包函数
def f1():
s = ‘1234‘
def f2():
print(len(s))
print(f2.__closure__)
return f2
res = f1()
res()
#输出的__closure__为None :不是闭包函数
s = ‘1234‘
def f1():
def f2():
print(len(s))
print(f2.__closure__)
return f2
res = f1()
res()
标签:其他 依赖倒置原则 返回值 并且 container global 修改 cell 存储
原文地址:https://www.cnblogs.com/maystar/p/12860415.html