函数引用
def test1():
print("--- in test1 func----")
ret = test1 # 获得函数引用
print( type(ret) )
print( id(ret) )
ret() # 使用函数引用调用函数
<class 'function'>
140212571149040
--- in test1 func----
函数名中保存着函数的入口地址,将函数名赋给变量,该变量中也保存了函数地址,称为
函数引用
,可以使用变量()
的形式调用函数
闭包
在函数内部再定义一个函数,并且内部函数用到了外部函数的变量,那么将这个内部函数以及用到的变量称之为
闭包
def 函数名():
局部变量...
def 内部函数名():
pass
return 内部函数名
- 应用场景1
def func(n):
def func_in(n_in):
print("in func_in 函数, n_in is %d" % n_in)
return n + n_in
return func_in
ret = func(20)
- 调用
func
函数,从返回值中获得func_in
函数的引用,并赋值给变量ret
- 数字
20
传递给func
函数的形参n
ret(100)
- 因为变量
ret
是func_in
函数的引用,所以ret(100)
相当于func_in(100)
- 数字
100
赋值给func_in
函数的形参n_in
print( ret(100) )
120
- 输出
func_in
函数的结果- 其中
n
赋值为20
,n_in
赋值为100
,所以结果为120
- 应用场景2
def line_conf(a, b):
def line(x):
return a*x + b
return line
line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5))
print(line2(5))
6
25
- 函数
line
与变量a、b
构成闭包
- 通过为
line_conf
的参数a
、b
赋值,可以确定函数的形式为y = x + 1
和y = 4x + 5
- 之后只要变换参数
a、b
,就可以获得不同的直线函数,并根据x
计算对应的y
值- 如果没有闭包,每次创建直线函数时都要同时说明
a、b、x
的值,就要传递更多的参数,增加了代码移植的难度
- 修改外部函数中的变量
def counter(start=0):
def incr():
nonlocal start
start += 1
return start
return incr
c1 = counter(5)
print(c1())
print(c1())
c2 = counter(50)
print(c2())
print(c2())
print(c1())
print(c1())
print(c2())
print(c2())
6
7
51
52
8
9
53
54
- 内部函数使用全局变量(函数最外层的变量),用
global
声明- 内部函数使用外部函数的局部变量(内部函数外,外部函数内的变量),用
nonlocal
声明
- end -