函数式编程思想的一种应用
目录
- Python中一切皆对象,函数也是对象。
- 闭包:函数和函数定义时(外部)的环境变量所构成的整体。
- 外部的环境变量必须在函数内部被引用。
def serve(): a = 10 b = 5 c = 3 def ser(x): return a*x*x + b*x + c # 外部的环境变量必须在ser函数内被引用,(被赋值不算)否则就不是一个闭包。 # 函数ser()和外部定义的环境变量a,b,c组成一个闭包 # return ser时实际上返回的是ser的闭包 return ser f = serve() print(f.__closure__) # ser闭包的每个环境变量对象 print(f.__closure__[0].cell_contents) # ser闭包的每个环境变量对象的值 # 输出 # (<cell at 0x025FEFD0: int object at 0x0FABD940>, <cell at 0x0260EC50: int object at 0x0FABD8F0>, <cell at 0x02768B90: int object at 0x0FABD8D0>) # 10
示例:
def f1():
a = 10
def f2():
a = 20(局部变量)
print(a)
#(1)
print(a)
#(2)
f2()
print(a)
#(3)
f1()
# a的值为:10 20 10
旅行者行走的问题(非闭包实现)
origin = 0
def go(step):
new_pos = origin + step
origin = new_pos
return new_pos
go(2)
#(会报错,局部变量origin在定义之前被使用。)
使用global
origin = 0
def go(step):
global origin
new_pos = origin + step
origin = new_pos
return new_pos
go(2)
# (将origin设置为全局变量是非常糟糕的,因为其它函数也可能改变origin值,函数的功能也就无从谈起了。)
闭包实现
origin = 0
def factory(pos):
# pos
def go(step):
nonlocal pos
# 如果没有此处的设置,仍然会报错,局部变量pos在定义之前被使用。
new_pos = pos + step
pos = new_pos
return pos
# 此处需要返回go函数的闭包
return go
tourist = factory(origin)
# tourist得到初始pos值为0的go闭包
print(tourist.__closure__[0].cell_contents) # 0
print(tourist(2)) # 2
print(tourist.__closure__[0].cell_contents) # 2
#(tourist的__closure__是一个tuple)
#(pos会记录上一次的值)
(环境变量是常驻内存的,容易造成内存泄漏,保存变量状态。)
(面向对象也可以实现函数式编程的内容。)