1,函数名的意义
函数体存储在一个内存块中,那么函数名就是这个内存块的首地址的标识符。
验证一下:
>>>defouter(x):
definner():
print(x)
returninner
>>>f1 = outer
outer为函数名,f1为函数别名。而outer()则为函数的调用,就是将首地址0x01730C48装入CPU的程序计数器PC中,程序从这里开始运行。
2,闭包
闭包在其它语言中也有这个概念,维基百科上的解释是:
在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
自由变量:如果一个变量在使用它的代码块中未被定义,那么这个变量就称作自由变量。
闭包例子:
defprint_msg():
# print_msg 是外围函数
msg ="free var"
defprinter():
# printer 是嵌套函数
print(msg)
return printer
another = print_msg()
# 输出freevar
another()
这里·的就是一个闭包,闭包本质上是一个函数,它由两部分组成,函数和变量。闭包使得这些变量的值始终保存在内存中。
一般情况下,函数中的局部变量仅在函数的执行期间可用,一旦执行过后,我们会认为变量将不再可用。然而,在这里我们发现print_msg()执行之后在调用another的时候msg变量的值正常输出了,这就是闭包的作用,闭包使得局部变量在函数外被访问成为可能。
闭包,顾名思义,就是一个封闭的包裹,里面包裹着自由变量,就像在类里面定义的属性
值一样,自由变量的可见范围随同包裹一起,哪里可以访问到这个包裹,哪里就可以访问到
这个自由变量。
闭包的作用:
闭包避免了使用全局变量,此外,闭包允许将函数与其所操作的某些数据(环境)关连起来。这一点与面向对象编程是非常类似的,在面对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。
一般来说,当对象中只有一个方法时,这时使用闭包是更好的选择。来看一个子:
defadder(x):
defwrapper(y):
returnx + y
returnwrapper
adder5 = adder(5)
# 输出 15
adder5(10)
# 输出 11
adder5(6)
所有函数都有一个属性,如果这个函数是一个闭包的话,那么它返回的是一个由 cell 对象 组成的元组对象。cell 对象的cell_contents 属性就是闭包中的自由变量。
>>>adder.__closure__
领取专属 10元无门槛券
私享最新 技术干货