【廖雪峰Python学习笔记】函数式编程

高阶函数

  • 面向过程的程序设计
    把大段代码拆成函数,通过一层层函数调用,可将复杂任务分解成若干简单的任务
  • 函数面向过程的程序设计的基本单位
  • 计算机Computer && 计算compute:
    Computer: CPU执行指令代码进行加减乘除运算,及各种条件判断和跳转指
    Compute: 数学意义的计算
    汇编语言是最贴近计算机的语言
    越低级的语言,越贴近计算机,抽象程度低,执行速度快 c
    越是高级的语言,越远离计算机,抽象程度高,执行效率低 lisp
  • 函数式编程的特点:函数可以作为参数,或作为返回值
  • Python不是纯函数式编程语言

返回函数

  1. 使用场景:后续代码中仍可能需要使用的函数
  2. 返回函数即使调用相同的参数,返回的也是不同的新函数
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							
  1. 闭包:调用一个函数返回一个函数后,其局部变量被新函数引用
>>> 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()

  1. 使用场景:传入不需要显示定义的函数
  2. 使用限制:只能有一个表达式,不能return,返回表达式的结果
>>> list(filter(lambda x : x % 2 == 1, range(1, 20)))
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

装饰器

  1. 使用场景:调用函数前自动打印日志,但不修改函数定义
  2. 自定义装饰器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

偏函数

  1. 偏函数Partial function:通过设定参数默认值,降低函数调用的难度
>>> import functools
>>> int2 = functools.partial(int, base=2) # 将int()函数中base参数设置默认值为2
  1. functools.partial设置默认参数后,可在函数调用时传入其他值;
  2. 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值