一、函数名的本质
函数名本质上就是函数的内存地址。
1、可以被当做值或变量引用
def func():
print(111)
print(func) #<function func at 0x00000218A911AB70> --函数在内存中的地址
f = func #将其传给变量f
print(f) #<function func at 0x00000279A5A6AB70>
f() #111
2、函数可以被当做容器类型的元素存储
#将其当做容器存储在列表中
def func1():
print(‘func1‘)
def func2():
print(‘func2‘)
def func3():
print(‘func3‘)
lis = [func1, func2, func3]
lis[0]() #func1
lis[1]() #func2
lis[2]() #func3
3、可以当做函数的参数和返回值
#当做参数和返回值
def func1():
print(‘func1‘)
def func(argv):
argv()
return argv #func1作为返回值
f = func(func1) #func1作为参数
f()
#输出
func1
func1
总结:
# 1、函数名的内存地址--print(函数名). # 2、函数名可以赋值给其他变量. # 3、函数名可以当做容器类的元素. # 4、函数名可以当做函数的参数. # 5、函数名可以当做函数的返回值. # 学名:第一类对象(first-class object)
# 总之:可以把函数名当做变量来用
二、闭包
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包(即:内层函数,对外层函数(非全局)的变量的引用)。
#闭包函数的基本用法
def func():
name = ‘eva‘
def inner():
print(name)
return inner
f = func()
f() #eva
检测闭包函数的公共属性:__closure__
#闭包函数
#输出结果如果有 cell 就是闭包函数
def wrapper():
name = ‘是闭包‘
def inner():
print(name) #是闭包
inner()
print(inner.__closure__) #(<cell at 0x000001945CE07588: str object at 0x000001945CE06B70>,)
wrapper()
# 非闭包函数
#输出结果如果是 None 就不是闭包函数
name = ‘不是闭包‘
def wrapper():
def inner():
print(name) #不是闭包
inner()
print(inner.__closure__) #None
wrapper()