1. 编程范式
编程范型、编程范式或程序设计法(英语:Programming paradigm),(范即模范、典范之意,范型即模
式、方法),是一类典型的编程风格,是指从事软件工程的一类典型的风格(可以对照方法学)。
如:函数式编程、面向过程编程、面向对象编程、指令式编程等等为不同的编程范型。在编程世界里更是这样,
各种编程范式在不同的场景下都各有优劣,谁好谁坏不能一概而论,下面就让我们来一 一解读它们
2. 面向过程编程
2.1 介绍
面向过程
(Procedure Oriented)是一种以过程为中心
的编程思想,是一种基础的方法,它考虑的是实际地实现
基于该思想编写程序就好比一条流水线首先分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,
使用的时候一个一个依次调用就可以了
比如拿学生早上起来去上学这件事说明面向过程,粗略的可以将过程拟为:
(1) 起床
(2) 穿衣
(3) 洗脸刷牙
(4) 去学校
# 第一步,起床
def get_up():
print('我起床了')
# 第二步,穿衣
def dress():
print("穿衣服")
# 第三步,洗脸刷牙
def brush_teeth():
print('刷牙,洗脸')
# 第四步,去学校
def go_school():
print("去学校")
get_up()
dress()
brush_teeth()
go_school()
这4步就是一步一步地完成,它的顺序很重要,你只需要一个一个地实现就行了。而如果是用面向对象的方法的
话,可能就只抽象出一个学生的类,它包括这四个方法,但是具体的顺序就不一定按照原来的顺序。
2.2 优缺点
[优点]
复杂问题流程化 , 进而简单化 , 这也是计算机最本质的工作模式 , 最喜欢的工作模式 , 一步一步的来
[缺点]
扩展性非常差
2.3 应用场景
- 不是所有的软件都需要频繁更迭 : 比如编写脚本
- 即便是一个软件需要频繁更迭,也不并不代表这个软件所有的组成部分都需要频繁迭代
3. 函数式编程
函数式编程(英语:)或称函数程序设计、泛函编程,是一种编程范式
函数式编程并非用函数编程这么简单,而是将将电脑运算视为函数运算,并且避免使用程序状态以及易变对象。
其中,λ演算(lambda calculus)为该语言最重要的基础。而且,λ演算的函数可以接受函数当作输入(引数)
和输出(传出值)。比起指令式编程,函数式编程更加强调程序执行的结果
而非执行的过程
,倡导利用若干简单
的执行单元让计算结果不断渐进
,逐层推导复杂的运算,而不是设计一个复杂的执行过程。表语言有: Haskell、
Erlang,而python并不是一门函数式编程语言,但是仍为我们提供了很多函数式编程好的特性,如lambda, map,
reduce, filter
3.1 lambda
对比使用def关键字创建的是有名字的函数,使用lambda关键字创建则是没有名字的函数,即匿名函数
语法如下 :
lambda 参数1,参数2 : 返回值
[定义]
lambda x, y: x + y # lambda自带一个return
print(lambda x, y: x + y)
[调用]
# 调用匿名函数 : 函数内存地址 + ()
# 方式一:
res = (lambda x, y: x + y)(1, 2)
print(res)
# 方式2:
x = (lambda x, y: x + y)
res1 = x(3, 5)
print(res1)
以上都不是匿名函数的真正调用方式 , 因为匿名函数的精髓就在于没有名字 , 你这又搞出来一个名字 , 那你干嘛不
用有名函数 def 关键字定义呢?
[应用场景]
匿名函数与有名函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,所以匿名函数用于临时使
用一次的场景,匿名函数通常与其他函数配合使用
[max函数]
接收一个可迭代对象 , 然后比较 , 返回最大值 , 可设置比较的依据
# 需求:打印出薪资最高的那个人的名字
salary_dic = {'tom': 100, 'alex': 500, 'jack': 200}
res = max(salary_dic)
# max直接迭代字典,只会把字典的key作为比较依据,我们需要把值作为依据,可指定key的值
def func(k):
return salary_dic[k]
res = max(salary_dic, key=func)
# max会把迭代的每一个值传递给key指定的函数内存地址当做实参,然后通过函数的返回值作为比较的依据
print(res) # alex
但是你发现了吗 , func这个函数 , 只适用于这次比较大小 , 没有其他可用的作用了 , 既然只用一次 , 那么用匿名函
数岂不美哉
# k就是函数的形参,实参在代码层面你是看不到的,但是执行起来会传参
res = max(salary_dic, key=lambda k: salary_dic[k])
print(res)
[min函数]
salary_dic = {'tom': 100, 'alex': 500, 'jack': 200}
# max取最大,min取最小
res1 = min(salary_dic, key=lambda k: salary_dic[k])
print(res1)
[stored函数]
sorted 排序
,也可以指定比较依据,默认reserve=False
,是从小到大排列,可以设为True,从大到小排列
salary_dic = {'tom': 100, 'alex': 500, 'jack': 200}
res2 = sorted(salary_dic, key=lambda k: salary_dic[k])
print(res2)
3.2 map
函数map、filter 、reduce都支持迭代器协议,可以用来处理可迭代对象
map
映射函数
# 1. 把列表中的人名都追加上_dsb
l = ["tao", 'fang', 'huang']
res = map(lambda name: name + "_dsb", l) # map会把l的值迭代出来交给前面打的函数,然后返回一个迭代器
print(res, type(res))
for i in res:
print(i)
print(res.__next__()) # 上面代码已经把迭代器里面的值取完了,再取就报错了
3.3 filter
filter
过滤函数
# 去掉有sb(帅逼)结尾的名字
l2 = ['tao_dsb', 'fang', 'huang']
res2 = filter(lambda name: not name.endswith("sb"), l2)
# filter会迭代l2里面的值,传递给lambda,如果返回值为true就保留原来的值,否则就过滤掉
print(list(res2))
3.4 reduce
reduce
在python3中已经不是内置函数了,但是在python2中还是
[不指定初始值]
from functools import reduce
l3 = [1, 2, 3, 4, ]
res3 = reduce(lambda x, y: x + y, l3)
# 可以指定初始值,如果不指定,默认从l中取出两个参数,得到的返回值作为下一次的一个参数
print(res3) # 10
[指定初始值]
res4 = reduce(lambda x, y: x + y, ['a','b','c'],"hello")
print(res4) # helloabc