一、函数对象
函数对象指的是函数可以被当作“数据”来处理,具体有以下四种使用方法:
1.1:函数可以被引用
def add(x, y):
return x+y
func = add # 函数可以赋值给另一个变量
print(func(1,3))
1.2:函数可以作为容器类型的元素
def add(x, y):
return x+y
dic = {'add':add, 'max':max}
print(dic)
# {'add': , 'max': }
print(dic['add'](1, 2))
# 3
1.3:函数可以作为参数传入另一个函数
def add(x, y):
return x+y
def foo(func, x, y):
return func(x, y)
print(foo(add, 5, 6)) # 11
1.4:函数可以作为返回值
def add(x, y):
return x+y
def bar():
return add
func = bar()
print(func(4,5)) # 9
1.5:嵌套函数里面,调用外层函数时,运行到内层的def语句,仅仅是完成对内层函数的定义,而不会去调用内层函数。
x = 99
def f1():
x = 88
print("from f1")
def f2():
print(x)
print("from f2")
f1() # from f1
1.6:局部作用域在函数结束之后会立即释放,但是enclosing(函数内部与嵌套函数之间的作用域)作用域在嵌套函数返回后,仍然有效。
x = 99
def f1():
x = 88
print("from f1")
def f2():
print(x)
print("from f2")
return f2
action = f1() # from f1
action()
# 88
# from f2
二、闭包函数
2.1:闭与包
基于函数对象的概念,可以将函数返回到任意位置去调用,但作用域的关系是在定义完函数时就已经被确定了的,与函数的调用位置无关。
x=1
def f1():
def f2():
print(x)
return f2
def f3():
x=3
f2=f1() #调用f1()返回函数f2
f2() #需要按照函数定义时的作用关系去执行,与调用位置无关
f3() #结果为1
因此函数被当做数据处理时,始终以自带的作用域为准。
在一个内部函数里,存在对外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被认为是闭包,外部函数被认为是闭包函数。
即闭包函数需要满足两个条件:
a:函数内部定义函数——嵌套函数
b:包含对外部作用域而非全局作用域的引用
def outer():
def inner():
print('inner func')
return inner
# 不是闭包函数,没有对外部作用域的引用
x= 1
def outer():
def inner():
print(f'x = {x}')
return inner
# 不是闭包函数,引用了全局作用域的变量
def outer():
x = 1
def inner():
print(f'x = {x}')
return inner
# 是闭包函数
def outer(x):
def inner():
print(f'x = {x}')
return inner
# 是闭包函数