-
Python中高阶函数与装饰器教程
1高阶函数
1.1 数学概念
回顾下数学知识:
y=f(x) 这是最开始接触的普通函数
y=g(f(x)) 这个就是我们接触到的高阶函数
在数学和计算机科学中,高阶函数至少应当是满足下面一个条件的函数:
1)接受一个或者多个函数作为参数
2)输出一个函数
程序中我们的高阶函数也类似
示例计数器的函数:
def counter(base):
def inc(step=1):
nonlocal base
base += step
return base
return inc
1.2 内建函数应用高阶函数举例
sorte(iterable[,key][,reverse]) 排序,返回一个列表
filter(function, iterable) 过滤可迭代对象的元素,返回一个迭代器
map(function, *iterable) -->map object 对多个可迭代对象的元素按照指定的函数进行映射,返回一个迭代器
2 装饰器
2.1 自定义高阶函数
柯里化Currying
自定义高阶函数前,先了解下柯里化Currying:
柯里化:指的是将原来接受两个参数的函数变成新的接收一个参数的函数,新的函数返回一个以原有第二个参数为参数的函数
z = f(x, y)转换成z=f(x)(y)
通过嵌套函数就可以把函数转换成柯里化函数
举例
def add(x,y):
return x+y
改变后
def add(x):
def _add(y):
nonlocalt x
retrun x+y
return _add
这就是一个简单的高阶函数
2.2 高阶函数应用--装饰器
引入:
存在一个add函数。
def add(x, y):
return x + y
这个add()太low了,我需要增强他的功能,譬如加入信息输出功能:
def add(x, y):
print("call add, {}+{}".format(x,y))
return x + y
上面的加法函数实现我的需求,但还是不够好,存在以下缺点:
1)打印语句的耦合太高。
2)add()属于业务功能,而输出信息属于非业务功能代码,类似日志的东东,放在add()函数不太合适。
那么改进下:
def add(x, y):
return x + y
def logger(fn):
print("开始业务执行")
x = fn(4, 5)
print("执行结束,结果:", x)
print(logger(add))
好了一些,那继续改进
def add(x,y):
return x+y
def logger(fn,x,y):
print("开始业务执行")
ret = fn(x,y)
print("执行结束",)
return ret
改进后,fn的参数仍受限制,只能针对含有两个参数的add,我想让logger适用的范围更大一些,譬如我有一个sum(x,y,z)
继续改进
def logger(fn,*args,**kwargs):
print("开始业务执行")
ret = fn(*args,**kwargs)
print("执行结束")
return ret
这个时候,进行柯里化
def logger(fn):
def _logger(*args, **kwargs):
print('before')
ret = fn(*args, **kwargs)
print('after')
return ret
return _logger
# 如下调用,python学习交流群:489111204
add = logger(add) # 因为函数调用的关系,参数add的引用用在函数内部保存
add(4, 5) # 调用的是内部保存的add引用,而非原本的add函数
Python将其改进为装饰器
#Python学习交流QQ群:489111204
def logger(fn):
def _logger(*args, **kwargs):
print('before')
ret = fn(*args, **kwargs)
print('after')
return ret
return _logger
@logger
def add(x,y):
return x+y
print(add(4, 10))
装饰器是高阶函数一个重要应用,是对传入函数的功能装饰或者是功能增强。
出处:https://www.cnblogs.com/python1111/p/17041319.html
栏目列表
最新更新
go语言写http踩得坑
【Python】爬虫笔记-从PyMySQL到DBUtils
【Python】爬虫笔记-开源代理池haipproxy使用
Python规范:提高可读性
C语言两结构体之间的成员互换
【爬虫实战项目】Python爬取Top100电影榜单
linux(Ubuntu)安装python
anaconda peompt 、labalimg 数据标注
【Python数据分析案例】python数据分析老番
【爬虫+情感判定+Top10高频词+词云图】“
一次SQL调优 聊一聊 SQLSERVER 数据页
聊一聊 SQLSERVER 的行不能跨页
再聊一下那 SQLSERVER 行不能跨页的事
大数据概述
支线第九篇:
数据库的值获取过来转换成Json数组的方法
支线第八篇:数据类型转换
支线第七篇:又是解决报错
支线第六篇:停下脚步,理清思路
支线第五篇:配置接口
【JS】原始类型是值类型吗?存储在栈上
C# List<T> 转 DataTable
C# List<T> 转 DataTable
C# List<T> 转 DataTable 方法修改版
使用插件式开发称重仪表驱动,RS232串口
实现简单的csv文件上传和bootstrap表格的下
第一百一十七篇: JavaScript 工厂模式和原型
第一百一十六篇: JavaScript理解对象
第一百一十五篇: JS集合引用类型Map
第一百一十四篇: JS数组Array(三)数组常