python 的高级特性:函数式编程,lambda表达式,装饰器
2019-06-26 09:01
489 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40421176/article/details/93708650
Python函数式编程只是借鉴函数式编程的一些特点,可以理解成一半函数式一半Python
需要讲述
返回函数
匿名函数
装饰器
偏函数
filter函数怎么写
返回值一定是一个布尔值
调用格式
2、装饰器的使用
实现对hello的扩展的案例
4、案例中对函数的装饰使用了系统定义的语法糖
一、Python语言的高级特性
函数式编程
- 基于Lambda演算的一种编程方式 程序中只有函数
- 函数可以作为参数,同样可以作为返回值
- 纯函数式编程语言:LISP,Haaskell
-
高阶函数
二、lambda表达式
- 函数:最大程度上复用代码 存在问题:如果函数很小,反而觉得麻烦
- 如果函数被调用次数少,则造成浪费
- 对于读者来说,造成阅读流程被迫中断
lambda表达式(匿名函数)
- 一个表达式,函数体相对简单
- 不是一个代码块,仅仅是一个表示式
- 可以有一个或多个参数,用逗号隔开
lambda表达式的用法
1、以lambda开头
2、紧跟一定的参数(如果有的话)
3、参数后用冒号和表达式主题隔开
4、只是一个表达式,没有return
#lambda表达式的用法 stm = lambda x: 100 * x a = stm(12) print(a) stm2 = lambda x,y,z: x+10*y+100*z b = stm2(4,5,6) print(b)
三、高阶函数
- 把函数作为参数使用的函数,叫做高阶函数 函数名称就是一个变量
- 既然函数名称是变量,则应该可以被当做参数传入另一个函数
#函数名称就是一个变量 def funA(): print("In funA") funB = funA funB() def funC(n): return n * 100 #在写一个函数,把传入参数乘以300倍 def funD(n): return funC(n) * 3 print(funD(9)) #写一个高阶函数 def funE(n,f): return f(n) * 3 print(funE(9,funC))
四、系统高阶函数
1、map
- 原意就是映射,即把集合或者列表的元素,每一个元素都按照一定的规则进行操作,生成一个新的列表或者集合
- map函数是系统提供的具有映射功能的函数,返回值是一个迭代对象
#由一个列表,相对每个元素都乘以10,得到新的列表 l1 = [i for i in range(10)] print(l1) l2 = [] for i in l1: l2.append(i * 10) print(l2) #利用map实现 def mulTen(n): return n * 10 l3 = map(mulTen,l1) print(type(l3)) #map类型是一个可迭代的结构 print(l3) for i in l3: print(i)
2、reduce
- 原意是归并,缩减
- 把一个可迭代对象最后归并成一个结果
- 对于作为参数的函数要求,必须有两个参数,必须有返回结果
- reduce需要导入functools包
from functools import reduce def Add(x,y): return x+y a = reduce(Add,[1,2,3,4,5]) print(a)
3、filter函数
- 过滤函数:对一组数据进行过滤,符合条件的数据会生成一个新的列表并返回
- 与map的比较
相同
都是对列表的每个元素进行操作 不同
1、map会生成一个跟原来数据相对应的新队列
2、filter不一定,只有符合条件的才会进入新队列
-
利用给定函数进行判断
filter(fun,date),fun是过滤函数,date是数据
#定义过滤函数#要求有输入,返回布尔值 def isEven(a): return a % 2 == 0 l = [3,4,5,12,45,14,3,11,51] rst = filter(isEven, l) print(type(rst)) print(rst) print([i for i in rst])
五、高阶函数-排序
- 把一个序列按照给定算法就行排序
- key:在排序前对每一个元素进行key函数运算,可以理解成按照kay函数定义的逻辑进行排序
- python2和python3相差巨大
- sorted函数
格式:
sorted(a,reverse),a是要进行排序的数据,reverse是正序或倒序的参数
reverse为False时为正序排列,为True时为倒序排列
默认reverse为False
a = [12,4,5,6,8,54,587,422,4679,52] al = sorted(a) print(al) al1 = sorted(a,reverse = True) print(al1) b = [12,-54,23,-5,5,48,-65,74,-78] #按照绝对值进行排序#abs是求绝对值的意思 b1 = sorted(b,key=abs) print(b1) #字符串排序 c = ['da','Da','fdsf','dfc','EFxc','Erv'] c1 = sorted(c) print(c1) c2 = sorted(c,key=str.lower) print(c2)
六、返回函数
- 函数可以返回具体的值
- 也可以返回一个函数作为结果
#定义一个普通函数 def myF(a): print('In myF') return None a = myF(2) print(a) #函数作为返回值返回,被返回的函数在函数体内定义 def myF2(): def myF3(): print('In myF3') return 3 return myF3 f3 = myF2() print(type(f3)) print(f3) f3() print(f3()) #复杂一点的返回函数的例子d def myF4(*args): def myF5(): rst = 0 for n in args: rst += n return rst return myF5 f5 = myF4(1,2,3,4,5,6) print(f5())
七、闭包(closure)
- 当一个函数在内部定义函数,并且内部函数应用外部函数的参数或者局部变量,当内部函数被当做返回值的时候,相关参数和变量保存在返回的函数中,这种结果叫做闭包
- 上例中的myF4就是一个标准的闭包
#闭包常见的坑 def count(): fs = [] for i in range(1,4): #定义一个函数f #f是一个闭包结构 def f(): return i*i fs.append(f) return fs f1,f2,f3 = count() print(f1()) print(f2()) print(f3())
- 上例中的问题
1、出现的问题:
造成上述问题的原因是返回函数引用了变量i,i并非立即执行,而是等到三个函数都返回的时候才统一使用,此时i已经变成了3,所以返回的都是3*3
所以,返回闭包时返回函数不能引用任何循环变量
2、解决方案:
再创建一个函数,用该函数的参数绑定循环变量的当前值,无论该循环变量以后怎么改变,已经绑定的函数参数值不在改变
如下
def count(): def f(j): def g(): return j*j return g fs = [] for i in range(1,4): fs.append(f(i)) return fs f1,f2,f3 = count() print(f1()) print(f2()) print(f3())
八、装饰器
- 一个普通的函数
def hello(): print('hello') return None hello() f = hello f() print(id(f)) print(id(hello)) #上述说明f和hello是同一个函数,也可以用以下方法验证 print(f.__name__) print(hello.__name__)
- 现在有新的需求,对hello的功能就行扩展,每次打印hello之前打印当前系统时间,实现这个功能又不能改变现有代码
- 这是就是用装饰器
- 1、装饰器定义: 在不改动函数代码的基础上无限制扩展函数功能的一种机制,本质上讲,装饰器是一个返回函数的高阶函数
-
使用@语法,即在每次要扩展到函数定义千使用@+函数名
import time #高阶函数,以函数作为参数 def printTime(f): def wrapper(*args,**kwargs): print("Time:",time.ctime()) return f(*args,**kwargs) return wrapper #上面定义了装饰器,使用的时候需要用到@,此符号是python的语法糖 @printTime def hello(): print("Hello") hello() @printTime def hello2(): print('hahah') hello2()
- 3、装饰器的好处 一次定义,可以装饰任何函数
- 一旦被其装饰,则把装饰器的功能直接添加到定义函数的功能上
- 而且不用改动定义函数的代码,非常安全,绿色
九、偏函数
- 参数固定的函数,相当于一个有特定参数的函数体-
- 需要使用funtools.partial模块
- 其作用是把一个函数某些参数固定,返回一个新函数
import functools int16a = functools.partial(int,base=16) b = int16a('a') print(b) help(int)
十、高级函数补充
1、zip
- 把两个可迭代的内容生成一个可迭代的tuple元素类型组成的内容
l1 = [1,2,3,4,5] l2 = [11,22,33,44,55] z = zip(l1,l2) print(type(z)) print(z) for i in z: print(i)
2、enumerate
- 跟zip功能比较像
- 对可迭代的对象里的每一个元素,配上一个索引,然后索引和内容构成tuple类型
l2 = [11,22,33,44,55] em = enumerate(l2) l = [i for i in em] print(l) em1 = enumerate(l2,start=100) ll = [i for i in em1] print(ll)
3、collections模块
- namedtuple
- deque
1、namedtuple
- tuple 类型
- 是一个可命名的tuple
import collections Point = collections.namedtuple("Point",['x','y']) p = Point(11,22) print(p.x) print(p[0]) Circle = collections.namedtuple('Ciecle',['x','y','r']) c = (100,150,50) print(c) print(type(c)) #检测namedtuple是否为tuple的子类 isinstance(c,tuple)
2、deque
- 比较方便的解决频繁删除插入带来的效率问题
from collections import deque q = deque(['a','b','c']) print(q)q.append('d') print(q) #从前面插入 q.appendleft('x') print(q)
3、defaultdict
- 当直接读取dict不存在的属性时,直接返回默认值
from collections import defaultdict d = {'one':1,'two':2,'three':3} print(d['one']) #print(d['four']) func = lambda:'杨朔' d1 = defaultdict(func) d1['one'] = 1 d1['two'] = 2 print(d1['one']) print(d1) print(d1['four'])
4、Counter
- 统计字符串的个数
from collections import Counter c = Counter('ksdcs,,csddscdsojdsvm,z.') #为什么下面不把ksdcs,,csddscdsojdsvm,z.作为键值,而是以其中每一个字符作为键值#这是因为需要括号里的内容为可迭代的 print(c) s = ('aa','dd','aa','dd','df','sd','aa') ss = Counter(s) print(ss
相关文章推荐
- Python的高级特性4:函数式编程
- python高级特性、函数式编程、面向对象
- python再复习(4)高级特性、函数式编程以及用法小结
- Python高级特性: 函数编程 lambda, filter,map,reduce
- Java8新特性Lambda表达式----函数式编程
- 畅游Python 六:基础函数 - 函数式编程和面向过程编程的区别、open函数、lambda表达式、内置参数列表、递归
- Python笔记(二)——高级特性|函数式编程
- Python入门 第四天(函数式编程、map、reduce、filter、排序函数、函数返回函数、闭包、匿名函数lambda)
- java1.8 lambda表达式 函数式编程 闭包
- Java8 Lambda表达式 函数式编程
- python函数式编程:匿名函数,装饰器,偏函数
- python高级编程-装饰器学习笔记
- Python 函数式编程之lambda
- Java8 Lambda表达式 函数式编程 方法引用
- 【Python笔记】Python的几个高级语法概念浅析:lambda表达式 && 闭包 && 装饰器
- Java8新特性Lambda表达式、函数式接口
- 【语言工具】Python闭包,装饰器,生成器,偏函数,函数式编程,lamda,map,reduce,filter
- Python函数式编程之lambda
- Java8 Lambda表达式 函数式编程
- python笔记11 - lambda函数,globals()/locals()函数,eval()exec()函数,闭包函数,函数式编程,高阶函数