本篇内容主要讲解“python高阶函数functools模块如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python高阶函数functools模块如何使用”吧!
functools模块提供了一些常用的高阶函数(处理其他可调用对象/函数的特殊函数;以函数作为输入参数,返回也是函数)。
functools模块中的高阶函数可基于已有函数定义新的函数:
cmp_to_key,
total_ordering,
reduce,
partial,
update_wrapper
wraps
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用于处理类方法。
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
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(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()用来自定义排序规则,可将比较函数(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]
是一个类装饰器,用于自动实现类的比较运算;类定义一个或者多个比较排序方法,类装饰器将会补充其余的比较方法。
被修饰的类必须至少定义 __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)
到此,相信大家对“python高阶函数functools模块如何使用”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。