本文实例讲述了Python函数式编程。分享给大家供大家参考,具体如下:

函数式编程就是一种抽象程度很高的编程范式,从计算机硬件->汇编语言->C语言->Python抽象程度越高、越贴近于计算,但执行效率也越低。纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

Python对函数式编程提供部分支持,支持高阶函数(函数可以作为变量传入),支持闭包(返回一个函数),有限地支持匿名函数。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

1、高阶函数

即可以通过变量名指向函数,函数通过变量名作为参数传给另一个函数,并通过变量名来使用。例如下面将开方函数math.sqrt作为参数传递给变量f,变量名f就指向了函数math.sqrt,再通过变量f使用该函数给x、y开方。

import math

def add(x, y, f):

return f(x) + f(y) # 函数作为参数传递给f来调用

res = add(25, 9, math.sqrt)

print(res)

map函数接收一个函数 f 和一个 list,并把函数 f 依次作用在 list 的每个元素上,得到一个iterators并返回。

def format_name(s):

return s[0].upper()+s[1:].lower() #将列表的每个元素首字母大写,其他小写

print(list(map(format_name, ['adam', 'LISA', 'barT'])))

#输出:['Adam', 'Lisa', 'Bart']

filter()根据判断函数f的结果自动过滤掉不符合条件的元素,以iterators返回剩下的元素

def is_odd(x):

return x % 2 == 1 # 过滤函数,x为奇返回True

f_res = filter(is_odd, [1, 4, 6, 7, 9, 12, 17])

print(list(f_res)) # 输出过滤后的结果list:1 7 9 17

sorted()函数用于对可迭代的对象进行排序,参数key=指定排序的关键字,这里可以借助functools.cmp_to_keys()将比较方法映射为自定义的方法。例如实现了降序排列,比较函数cmp返回值 -1 代表a 应该排在 b 的前面,如果a排在b 的后面返回 1。如果 a、b相等返回 0。

import functools

def cmp(a, b):

if b < a:

return -1

if a < b:

return 1

return 0

a = [1, 2, 5, 4]

print(sorted(a, key=functools.cmp_to_key(cmp)))

2、匿名函数和闭包

有时函数简单到只有一个表达式时,为了简化代码可以使用匿名函数来代替,匿名函数一般形式为lambda 参数:返回表达式,例如lambda x:x*x,就是传入x参数并返回x的平方。例如在使用map()函数时需要传入一个函数用于list的元素,此时可以使用匿名函数作为参数

lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]

res = map(lambda x: x * x, lst) # 将匿名函数作用于lst

print(list(res))

函数的闭包(Closure)是指内层函数引用了外层函数的变量,然后将内层函数像变量一样返回的情况。例如函数calc_prod()接收一个list,在其内部定义一个函数multiply,计算list元素的乘积并将multiply返回。用f接收calc_prod()的返回函数,并在之后调用该函数

def calc_prod(lst):

def multiply():

res=1

for i in lst:

res=res*i

return res

return multiply # 将函数返回

f = calc_prod([1, 2, 3, 4]) # 接收返回函数

print(f()) # 调用返回函数

注意在函数闭包时要确保引用的局部变量在函数返回后不能变。例如下面的例子,当count()函数返回3个函数时,由于f1、f2、f3并没有被调用,所以并未计算 i*i。当 f1 被调用时,这3个函数所引用的变量 i 的值已经变成了3,所以此时使用的变量i的值已经发生了改变,三个函数的输出都是9。

def count():

fs = []

for i in range(1, 4):

def f():

print(i) # 函数f1()调用时i已经变为3

return i*i

fs.append(f)

return fs

f1, f2, f3 = count()

print(f1()) # 输出9而不是1

3、函数装饰器

函数装饰器是指在原有函数的基础上对函数作修改和装饰操作。其基本思想是,既然函数可以像变量一样作为参数传入并且返回,那么我们可以将原来的函数传入装饰器函数,然后增加我们需要的操作,之后在将原函数返回出来。

例如下面定义了一个装饰器log用于打印函数名称,原函数作为参数f传入。在装饰器中定义新的函数fn,其中参数列*args和**kw代表自适应参数个数,防止不同参数个数的函数在使用装饰器时不匹配。在新函数fn中输出原函数的名称,之后将原函数原封不动地调用一遍并返回出去。最后返回新函数。

在使用装饰器时,只需要在函数的定义前加一行@装饰器名

def log(f): # 定义装饰器log

def fn(*args, **kw): # 定义新函数

print('函数名: ' + f.__name__) # 打印函数名

return f(*args, **kw) # 在新函数中调用原函数并返回结果

return fn # 返回新函数

@log # 为函数add添加装饰器

def add(x, y):

return x + y

print(add(1, 2))

如果希望给装饰器传入一个参数,则需要定义三重嵌套的函数,在最外层增加一层函数用于接收参数。例如希望在打印函数名之前输出传入的参数“DEBUG”

def log(prefix):

def log_decorator(f):

def wrapper(*args, **kw):

print '[%s] %s()...' % (prefix, f.__name__)

return f(*args, **kw)

return wrapper

return log_decorator

@log('DEBUG') # 为装饰器传入参数

def test():

pass

test()

由于装饰器实际上是创建了新的函数fn并替代了原函数,所以原函数的相关信息例如函数名会被覆盖,可以用@functools.wraps(f)来复制原函数的信息以保留下来。

import functools

def log(f):

@functools.wraps(f)

def fn(*args, **kw):

print 'call...'

return f(*args, **kw)

return fn

偏函数可以为函数填上一个固定的参数值,从而生成一个新的函数。例如原函数add需要两个参数x、y,通过指定y=1得到偏函数add1,这个函数只需要输入一个参数x,从而计算x+1的值。

import functools

def add(x, y):

return x + y

add1 = functools.partial(add, y=1)

print(add2(3)) # 输出结果为4

希望本文所述对大家Python程序设计有所帮助。

python函数编程实例_Python函数式编程实例详解相关推荐

  1. 简述python文件操作_Python 文件操作的详解及实例

    Python 文件操作的详解及实例 一.文件操作 1.对文件操作流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 现有文件如下: 昨夜寒蛩不住鸣. 惊回千里梦,已三更. ...

  2. python编写函数_python函数式编程

    函数式编程是使用一系列函数去解决问题,按照一般编程思维,面对问题时我们的思考方式是"怎么干",而函数函数式编程的思考方式是我要"干什么". 至于函数式编程的特点 ...

  3. python socket 主动断开_Python网络编程tcp详解(基础篇十四)

    网络编程tcp 1 TCP详解 <1> tcp概述 TCP:英文全拼(Transmission Control Protocol)简称传输控制协议,它是一种面向连接的.可靠的.基于字节流的 ...

  4. predicate java 作用_Java函数式编程接口详解之Predicate

    一.初识 Predicate是Java提供的重要的函数编程接口之一,作用主要是用于逻辑判断. 首先看看源码: @FunctionalInterface public interface Predica ...

  5. python输出命令_Python输出各行命令详解

    创建main.py文件并粘贴下面代码 点击右键运行Debug 'main'后,下方的Debug窗口会出现ImportError: No module named 'bottle'这样的提示,提示导入b ...

  6. python 相对导入_Python相对导入机制详解

    Google FEB 26TH, 2015 Python相对导入机制详解 这个答案能解释大多关于 relative import,即相对导入的疑惑,讲解十分详尽清晰,算是 SO 上被低估的一个答案. ...

  7. python pdb 安装_Python调试工具pdb使用详解

    Python调试工具pdb使用详解 [简介] pdb是Python自带的一个包,为python程序提供了一种交互的源代码调试功能. [使用方法] 1. 使用命令: python -m pdb xxx. ...

  8. python通过银行卡号_python面向对象编程实例---银行账号

    转载自python面向对象编程示例---银行账号 | 酷python​www.coolpython.net 在最初接触面向对象编程时,你会感到有些不习惯,但这种编程范式却有助于我们思考问题,前提是你准 ...

  9. python结巴分词实例_python 结巴分词(jieba)详解

    "结巴"中文分词:做最好的 Python 中文分词组件 "Jieba" (Chinese for "to stutter") Chinese ...

最新文章

  1. 6个超实用的Sudo命令使用技巧
  2. Harbor镜像仓库部署
  3. Apache Kafka-SpringBoot整合Kafka发送复杂对象
  4. 200 计算机网络之物理层思维导图小结
  5. 面试官 | 如何提高服务器的并发能力?
  6. 利用权限禁止QQ的自动升级(QQUpdateCenter)
  7. ORACLE用SYS登录报ORA-28009:connection as SYS should be as SYSDBA OR SYSOPER解决方法
  8. iOS开发值多线程简单介绍
  9. 【机器学习】竞争神经网络(Competitive Neural Network)的python实现
  10. [Java]图书管理系统
  11. Python爬取图片
  12. snf快速开发平台试用演示地址
  13. 全球最强大脑在哪里?阿里小蜜算法团队在寻找
  14. 如何把照片压缩到20k一下_如何将一寸照片压缩到20k以内?
  15. 国外数据下载(阿里云+七牛云)
  16. python 傅里叶变换_【python学习笔记】21:numpy傅里叶变换
  17. 【2022年】Win11修改锁屏界面、登录界面背景图片方法(亲测有效)
  18. Python小白到老司机,快跟我上车!基础篇(十八)
  19. pcie读写ddr_5.3 存储器、I/O和配置读写请求TLP
  20. 正版授权|FastStone Capture 专业屏幕截图录屏工具软件 商业版,支持商业用途。

热门文章

  1. java上传图片特征码到服务器,记一个Base64编码后经网络传输产生的问题
  2. html5 PHP 分片上传,H5分片上传含前端JS和后端处理(thinkphp)
  3. 什么是Selenium?如何使用Selenium进行自动化测试
  4. mysql 记录更新时间_MySQL表内更新时,自动记录时间
  5. 剑指offer面试题[40]-数组中只出现一次的数字
  6. Java21天打卡Day5-ifelse
  7. oracle 认证考试题目,Oracle OCP 19c 认证1Z0-082考试题库(第1题)
  8. 案例 自动办公_国浩分享 | 非诉讼律师办公神器盘点
  9. Android跟踪进度条,android快递跟踪进度条
  10. 配置不成功_在windows下配置sendmail服务器