python高阶函数functools模块的具体使用
作者:alwaysrun 发布时间:2022-12-08 09:03:15
functools模块提供了一些常用的高阶函数(处理其他可调用对象/函数的特殊函数;以函数作为输入参数,返回也是函数)。
functools模块
functools模块中的高阶函数可基于已有函数定义新的函数:
cmp_to_key,
total_ordering,
reduce,
partial,
update_wrapper
wraps
reduce
reduce(function, iterable[, initializer])对一个可迭代数据集合中的所有数据进行累积。
function:接受两个参数的函数;
sequence:可迭代对象(tuple/list/dict/str);
initial:可选初始值;
# 累加
reduce(lambda x,y:x+y, [1,2,3,4]) # 10
# 逆序字符串
reduce(lambda x,y:y+x, 'abcdefg') # 'gfedcba'
partial/partialmethod
partial用于"冻结"函数的部分参数,返回一个参数更少、使用更简单的函数对象。使用时,只需传入未冻结的参数即可。partialmethod用于处理类方法。
functools.partial(func[, *args][, **keywords])返回一个新的partial对象:
func:一个可调用的对象或函数;
args:要冻结的位置参数;
keywords:要冻结的关键字参数。
def add(a, b, note="add"):
result = a + b
print(f"{note} result: {result}")
return result
add3 = functools.partial(add, 3)
add5 = functools.partial(add, 5, note="partialed")
print(add3(1)) # add result: 4
print(add3(2, note="partial3")) # partial3 result: 5
print(add5(3)) # partialed result: 8
partialmethod用于类中的方法
class Cell(object):
def __init__(self):
self._alive = False
@property
def alive(self):
return self._alive
def set_state(self, state):
self._alive = bool(state)
set_alive = functools.partialmethod(set_state, True)
set_dead = functools.partialmethod(set_state, False)
c = Cell()
print(c.alive) # False
c.set_alive()
print(c.alive) # True
wraps/update_wrapper
functools.update_wrapper(wrapper, wrapped [, assigned] [, updated])更新一个包裹(wrapper)函数,使其看起来更像被包裹(wrapped)的函数(即把 被封装函数的__name__、__module__、__doc__和 __dict__都复制到封装函数去。wraps是通过partial与update_wrapper实现的。
通常,经由被装饰(decorator)的函数会表现为另外一个函数了(函数名、说明等都变为了装饰器的);通过wraps函数可以消除装饰器的这些副作用。
def wrapper_decorator(func):
@functools.wraps(func) # 若是去掉此wraps,则被装饰的函数名称与说明都变为此函数的
def wrapper(*args, **kwargs):
"""doc of decorator"""
print('in wrapper_decorator...')
return func(*args, **kwargs)
return wrapper
@wrapper_decorator
def example():
"""doc of example"""
print('in example function')
example()
# in wrapper_decorator...
# in example function
print(example.__name__, "; ", example.__doc__) # example ; doc of example
singledispatch/singledispatchmethod
singledispatch将普通函数转换为泛型函数,而singledispatchmethod(3.8引入)将类方法转换为泛型函数:
泛型函数:是指由多个函数(针对不同类型的实现)组成的函数,调用时由分派算法决定使用哪个实现;
Single dispatch:一种泛型函数分派形式,基于第一个参数的类型来决定;
dispatch使用:
singledispatch装饰dispatch的基函数base_fun(即,注册object类型);
注册后续分发函数使用装饰器@{base_fun}.register({type}),注册每种需要特殊处理的类型;
分发函数名称无关紧要,_是个不错的选择;
可以叠放多个register装饰器,让同一个函数支持多种类型;
# 缺省匹配类型,注册object类型(与后续注册类型都不匹配时使用)
@functools.singledispatch
def show_dispatch(obj):
print(obj, type(obj), "dispatcher")
# 匹配str字符串
@show_dispatch.register(str)
def _(text):
print(text, type(text), "str")
# 匹配int
@show_dispatch.register(int)
def _(n):
print(n, type(n), "int")
# 匹配元祖或者字典
@show_dispatch.register(tuple)
@show_dispatch.register(dict)
def _(tup_dic):
print(tup_dic, type(tup_dic), "tuple/dict")
### 打印注册的类型:
# dict_keys([<class 'object'>, <class 'str'>, <class 'int'>, <class 'dict'>, <class 'tuple'>])
print(show_dispatch.registry.keys())
show_dispatch(1)
show_dispatch("xx")
show_dispatch([1])
show_dispatch((1, 2, 3))
show_dispatch({"a": "b"})
# 1 <class 'int'> int
# xx <class 'str'> str
# [1] <class 'list'> dispatcher
# (1, 2, 3) <class 'tuple'> tuple/dict
# {'a': 'b'} <class 'dict'> tuple/dict
cmp_to_key
cmp_to_key()用来自定义排序规则,可将比较函数(comparison function)转化为关键字函数(key function):
比较函数:接受两个参数,比较这两个参数,并返回0、1或-1;
关键字函数:接受一个参数,返回其对应的可比较对象;
test = [1, 3, 5, 2, 4]
test.sort(key=functools.cmp_to_key(lambda x, y: 1 if x < y else -1))
print(test) # [5, 4, 3, 2, 1]
total_ordering
是一个类装饰器,用于自动实现类的比较运算;类定义一个或者多个比较排序方法,类装饰器将会补充其余的比较方法。
被修饰的类必须至少定义 __lt__(), __le__(),__gt__(),__ge__()中的一个,以及__eq__()方法。
如,只需定义lt与eq方法,即可实现所有比较:
@functools.total_ordering
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __lt__(self, other):
if isinstance(other, Person):
return self.age < other.age
else:
raise AttributeError("Incorrect attribute!")
def __eq__(self, other):
if isinstance(other, Person):
return self.age == other.age
else:
raise AttributeError("Incorrect attribute!")
mike = Person("mike", 20)
tom = Person("tom", 10)
print(mike < tom)
print(mike <= tom)
print(mike > tom)
print(mike >= tom)
print(mike == tom)
来源:https://blog.csdn.net/alwaysrun/article/details/129767090
猜你喜欢
- 注意,在改变数值之前锁定应用,确保一段时间里只有一个客户执行该语句。<SCRIPT LANGUAGE="VBScr
- 版权所有:Copyright 1997 Netscape Communications Corporation原文链接:Object Hie
- 基本的网站页面设计元素布局比例统计,给大家做个参考,看看您的网站是否和下面的统计一致:标志图案:位置统计结果左上角84%右上角6%上方居中6
- 目录前后端传输数据的编码格式Ajax提交urlencoded格式数据Ajax通过FormData上传文件Ajax提交Json格式数据Ajax
- 在 Java 中打印当前线程的方法栈,可以用 kill -3 命令向 JVM 发送一个 OS 信号,JVM 捕捉以后会自动 dump 出来;
- 阅读上一篇:打造设计你自己的字体 ⅠMyFonts.com上销售的字体总数已经超过55,000个。现有字体的巨大数量表明了一个事实:我们在设
- 远程调用使得调用远程服务器的对象、方法的方式就和调用本地对象、方法的方式差不多,因为我们通过网络编程把这些都隐藏起来了。远程调用是分布式系统
- 这将为我们的团队节省每天重复的数据处理时间......简介如果你目前在一个数据或商业智能团队工作,你的任务之一可能是制作一些每日、每周或每月
- 体系结构 Microsoft按照客户/服务器体系结构的分布进行操作。这种方法产生不必要的代价和复杂性。在Internet中,Oracle已经
- 今天网页调试的时候在线订单出现错误:Server 对象 错误 'ASP 0178
- 有时候我们没办法得到pdf或者word文档,这个时候会使用手机或者相机进行拍照,往往会出现背景,打印出来就是灰色的或者有黑色的背景,这个时候
- asp自定义错误显示方法:<html><head><meta http-equiv="Co
- 一旦被黑客获取到webshell,黑客就知道了你的sqlserver管理员密码,如果sqlserver再没有经过安全设置那么黑客很容易就提权
- 如何提高SQL Server数据库的性能,该从哪里入手呢?笔者认为,该遵循从外到内的顺序,来改善数据库的运行性能。如下图: 第一层
- 前言:本文的主要内容是介绍Python中的列表及其方法的使用,涉及到的方法包括对列表元素进行修改、添加、删除、排序以及求列表长度等,此外还介
- 前言不知道大伙有没有看到过这一句话:“中国(疫苗研发)非常困难,因为在中国我们没有办法做第三期临床试验,因为没有病人了。
- 这篇文章主要介绍了Python OrderedDict的使用案例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- 前言:前两天用Python实现了ftp服务器。在小项目中就用到了反射。因此写个笔记巩固下。反射的定义:检测和修改它本身状态或行为的一种能力(
- 本文实例为大家分享了python多线程同时接受和发的具体代码,供大家参考,具体内容如下'''模仿qq 同时可以发送信
- 新人小菜鸟又来写博客啦!!!没人表示不开心~~(>_<)~~今天我来弄一个简单的关键词提取的代码文章内容关键词的提取分为三大步: