函数式编程
原则
写代码要遵循==开发封闭==原则,虽然这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即:
封闭:已实现的功能代码块
开放:对扩展开发
内容
装饰器
1 | def w1(func): |
当写完这段代码后(函数未被执行、未被执行、未被执行),python解释器就会从上到下解释代码,步骤如下:1
2def w1(func): ==>将w1函数加载到内存
没错,从表面上看解释器仅仅会解释这两句代码,因为函数在没有被调用之前其内部代码不会被执行。
从表面上看解释器着实会执行这两句,但是
@w1 这一句代码里却有大文章
@函数名
: 是python的一种语法糖。
如上例 @w1
内部会执行以下操作
: 执行w1函数,并将 @w1
下面的 函数 作为 w1 函数的参数
即:@w1
等价于 w1(f1)
。
所以,内部就会去执行:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17def inner:
#验证
return f1() # func是参数,此时 func 等于 f1
return inner # 返回的 inner,inner代表的是函数,非执行函数
# 其实就是将原来的 f1 函数塞进另外一个函数中。
# 将执行完的 w1 函数返回值赋值给@w1下面的函数的函数名
# w1函数的返回值是:
def inner:
#验证
return 原来f1() # 此处的 f1 表示原来的f1函数
# 然后,将此返回值再重新赋值给 f1,即:
new_f1 = def inner:
#验证
return 原来f1()
如此一来, 即执行了验证的功能,又执行了原来 f 函数的内容,并将原 f1 函数返回值,
返回给业务调用着。
参数传递
1 | # 一个参数: |
问题: 装饰具有处理n个参数的函数的装饰器?
1 | def w1(func): |
问题:一个函数可以被多个装饰器装饰吗?
1 | def w1(func): |
Lambda函数(匿名函数)
- 函数 : 最大程度地复用代码
- 存在问题:若函数很小,很短,则会造成啰嗦,不方便阅读代码
- lambda表达式
- 一个表达式,函数体相对简单
- 用法
- 以lambda开头
- 紧跟一定的参数
- 参数后面用冒号和表达式主题分开
- 只是一个表达式,没有return
- 实例
stm = lambda x: 100 * x
stm(89)
==>8900
高阶函数
- 定义 : 把函数作为参数使用的函数
- 注意
- 函数名称就是一个变量,即函数可以作为参数
- 举例
1
2
3
4
5def funA(n):
return n * 100
def funB(n):
return funA(n) * 3
map函数
- 对队列里的每个元素进行操作,即映射操作
- map函数是系统提供的具有映射功能的函数,返回值是一个迭代对象,类型为map类
- 注意:若用列表生成式得到的结果为空
- 格式:
map(func, *iterables)
1 | # map举例 |
reduce函数
- 作用: 归并,缩减 ,把可迭代对象最后归并为一个结果
- 作为参数的函数要求:
- 必须有两个参数
- 必须有返回结果
- 理解 :
reduce([1,2,3]) == f(f(f(1),2),3)
即函数嵌套 - 注意: reduce需要导入functools包
1 | from functools import reduce |
filter 函数
过滤函数:对一组数据进行过滤,符合条件的数据会产生一个新的列表返回
与map函数比较
- 相同 :
- 都对列表的每个元素逐一进行操作
不同 :
- map 会生成一个跟原来数据相对应的新队列
- filter 不一定,只有符合条件的才会进入新队列
filter函数写法
- 利用给定函数进行判断
- 返回值为一个布尔值
- 调用格式 : filter(f,data) f 为过滤函数 data 为数据
1 | # 案例 过滤偶数数据形成新列表 |
- 返回的filter内容是一个可迭代对象,需要逐个输出
排序
- 把一个序列按照给定算法进行排序
- key : 在排序前,对每一个元素进行 key 函数运算,可理解为按照 key 函数定义的逻辑进行排序 (key函数为排序函数的内嵌参数)
- python2 python3 的差别较大
1 | # 排序案例1 |