高阶函数
- 面向过程的程序设计:
把大段代码拆成函数,通过一层层函数调用,可将复杂任务分解成若干简单的任务 - 函数是面向过程的程序设计的基本单位
- 计算机Computer && 计算compute:
Computer: CPU执行指令代码进行加减乘除运算,及各种条件判断和跳转指
Compute: 数学意义的计算
汇编语言是最贴近计算机的语言
越低级的语言,越贴近计算机,抽象程度低,执行速度快 c
越是高级的语言,越远离计算机,抽象程度高,执行效率低 lisp - 函数式编程的特点:函数可以作为参数,或作为返回值
- Python不是纯函数式编程语言
返回函数
- 使用场景:后续代码中仍可能需要使用的函数
- 返回函数即使调用相同的参数,返回的也是不同的新函数
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
调用lazy_sum(*args)时,每次返回新的函数
>>> f1 = lazy_sum(1,3,5,7,9) # f1返回的是函数sum
>>> f1
<function lazy_sum.<locals>.sum at 0x102f32158>
>>> f1()
25
>>> f2 = lazy_sum(1,3,5,7,9) # f2返回的是一个新的函数sum
>>> f1 == f2 # f1与f2传入相同的参数,但在调用的时候,每次返回新的函数
False
- 闭包:调用一个函数返回一个函数后,其局部变量被新函数引用
>>> def count():
... fs = []
... for i in range(1, 4):
... def func():
... return i*i
... fs.append(func)
... return fs
>>> f = count() # 返回三个函数组成的列表
>>> f # 三个函数不相同
[<function count.<locals>.f at 0x1091540d0>, <function count.<locals>.f at 0x109154400>, <function count.<locals>.f at 0x109154488>]
>>> f[1]() # 先返回三个函数,后执行函数。故此时,他们引用的变量均为3
9
>>> f[2]()
9
>>> f[3]()
9
tips:返回闭包时,返回函数尽量不要引用循环变量,或后续会发生变化的变量
匿名函数
lambda()
- 使用场景:传入不需要显示定义的函数
- 使用限制:只能有一个表达式,不能return,返回表达式的结果
>>> list(filter(lambda x : x % 2 == 1, range(1, 20)))
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
装饰器
- 使用场景:调用函数前自动打印日志,但不修改函数定义
- 自定义装饰器Decorator步骤:
- 定义装饰器decorator
def log(text = ''):
def decorator(func):
def wrapper(*args, **kw):
# func.__name__用于获取函数名
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
- 使用装饰器
@log('execute')
def now():
print('2019-05-06')
相当于:
>>> log('execute')(now)()
execute wrapper():
execute now():
2019-05-06
- 缺点:原始函数的__name__ 变成为自定义的 wapper
- 解决方案: 使用Python内置的 functions.wraps
import functools
def log(text = ''):
def decorator(func):
@functions.wraps()
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
偏函数
- 偏函数Partial function:通过设定参数默认值,降低函数调用的难度
>>> import functools
>>> int2 = functools.partial(int, base=2) # 将int()函数中base参数设置默认值为2
- functools.partial设置默认参数后,可在函数调用时传入其他值;
- functools.partial最后接受函数对象、*args和**kw三部分参数
import functools
def add(*args, **kwargs):
print(*args)
print('-' * 20)
for key, value in kwargs.items():
print('%s : %s' % (key, value))
add_partial = functools.partial(add, 10, k1 = 10, k2 = 20)
print add_partial(10, 2, 3, k1 = 40, k3 = 30)
返回结果为
10 10 2 3
--------------------
k1 : 40
k2 : 20
k3 : 30