Python 闭包
1. 函数引用
2. 闭包
1. 函数引用
1 >>> def test(): # 函数的定义,可理解为函数名指向了该函数体 2 ... print("---test---") 3 ... 4 >>> test() # 执行该函数体 5 ---test--- 6 >>> test # test指向了该函数体 7 <function test at 0x0313D460> 8 >>> b = test # b也指向了该函数体 9 >>> id(test) 10 51631200 11 >>> id(b) # b()也执行了该函数体 12 51631200 13 >>> b() 14 ---test---
2. 闭包
在函数内部再定义一个函数,并且这个内部函数引用到了外部函数作用域内的变量,则将这个内部函数以及引用到的外部参数一并称为闭包。
本质上,闭包是将函数内部和函数外部连接起来的桥梁。
1 def test(number_out): 2 print("outer---start") 3 4 def test_in(number_in): 5 print("number_out={}, number_in={}".format(number_out, number_in)) 6 return number_out + number_in 7 8 print("outer---end") 9 10 return test_in # 外部函数返回的是内部函数的引用 11 12 13 ret = test(100) # ret指向了内部函数,此参数100可以理解为基数 14 print("-" * 40) 15 print(ret(200)) # 100 + 200 = 300 16 print(ret(300)) # 100 + 300 = 400
执行结果:
outer---start outer---end ---------------------------------------- number_out=100, number_in=200 300 number_out=100, number_in=300 400
闭包的应用示例
1 def line_out(a, b): 2 3 def line_in(x): 4 return a * x + b 5 6 return line_in 7 8 9 line1 = line_out(1, 1) 10 line2 = line_out(2, 3) 11 print(line1(5)) # 即 1*5 + 1 = 6 12 print(line2(5)) # 即 2*5 + 3 = 13 13 print(line2(3)) # 即 2*3 + 3 = 9
这个例子中,函数 line_in 与变量 a、b 构成闭包。在创建闭包的时候,我们通过 line_out 的参数 a、b 说明了这两个变量的取值,这样,我们就确定了函数的最终形式(y = x + 1 和 y = 2x + 3)。我们只需要变换参数a、b,就可以获得不同的直线表达函数。由此,我们可以看到,闭包也具有提高代码复用性的作用。
如果没有闭包,我们需要每次创建直线函数的时候同时说明 a、b、x,这样就需要更多的参数传递,也减弱了代码的可移植性。
闭包再理解
- 闭包似乎优化了变量,原来需要类对象完成的工作,闭包也可以完成。
- 由于闭包引用了外部函数的局部变量,则容易导致外部函数的局部变量没有及时释放,消耗内存。