参考文章
高阶函数
特殊的函数,特殊在能将函数作为参数及返回值。
好处在于借助其可以实现 闭包,装饰器 这样的东西。
闭包
是由函数和与其相关的引用环境组合成的实体。实现方式是作为高阶函数的返回值(函数),并和高阶函数内部的自由变量进行了关联(“引用环境”)。
特点是可以实现延迟计算,因为必须调用闭包才会真正进行计算。
不知道Mathematica的延迟定义是否也是基于这样的原理?
所有的函数都有__closure__
属性,如果一个函数是闭包,那么它返回一个cell
对象组成的元组。这个元组保存的内容就是和闭包关联的引用环境,cell
对象的cell_contents
属性就是闭包中的自由变量。
>>> def adder(x):
>>> def wrapper(y):
>>> return x + y
>>> return wrapper
# 函数 f 就是一个闭包
# 参数 5 是高阶函数的局部变量
# 同时也是和闭包关联的自由变量
# 基于此才能在脱离 adder 函数后仍能被访问到
>>> f = adder(5)
>>> adder.__closure
>>> f.__closure__
(<cell at 0x7f23dcc31948: int object at 0x296f0f8>,)
>>> f.__closure__[0].cell_contents
5
装饰器
是一个函数,还是高阶函数,可以返回一个闭包。
干的事情是重写(装饰)函数,并返回装饰过的函数。
作用是提高代码重用率,简化代码,增加可读性。
装饰过的函数与原始版本的区别在于添加的装饰品,可以实现实现一些通用的功能,如打印函数运行时间,记录函数创建日志等等。
使用——装饰器 可以嵌套多层使用,即是说自定义的装饰器中的包装函数也可以被别的装饰器装饰。