Python的函数名与闭包

一、函数名的本质

函数名本质上就是函数的内存地址。

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

 1、检测闭包函数的公共属性:__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()

 2、带有参数的闭包函数

#带有参数的闭包函数
def wrapper(a):     #a是外部传入的参数
    b = 10
    def inner():
        #在内函数inner中 用到了外函数的临时变量b
        print(a + b)        #20
        return a + b
    inner(a)
wrapper(10)

 闭包的作用:

  保护内存,闭包函数在内存的中局部内存空间不会随着函数的结束而结束
原文地址:https://www.cnblogs.com/lioushell/p/8405687.html