您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“python高階函數(shù)functools模塊如何使用”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“python高階函數(shù)functools模塊如何使用”吧!
functools模塊提供了一些常用的高階函數(shù)(處理其他可調(diào)用對(duì)象/函數(shù)的特殊函數(shù);以函數(shù)作為輸入?yún)?shù),返回也是函數(shù))。
functools模塊中的高階函數(shù)可基于已有函數(shù)定義新的函數(shù):
cmp_to_key,
total_ordering,
reduce,
partial,
update_wrapper
wraps
reduce(function, iterable[, initializer])對(duì)一個(gè)可迭代數(shù)據(jù)集合中的所有數(shù)據(jù)進(jìn)行累積。
function:接受兩個(gè)參數(shù)的函數(shù);
sequence:可迭代對(duì)象(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用于"凍結(jié)"函數(shù)的部分參數(shù),返回一個(gè)參數(shù)更少、使用更簡(jiǎn)單的函數(shù)對(duì)象。使用時(shí),只需傳入未凍結(jié)的參數(shù)即可。partialmethod用于處理類方法。
functools.partial(func[, *args][, **keywords])返回一個(gè)新的partial對(duì)象:
func:一個(gè)可調(diào)用的對(duì)象或函數(shù);
args:要凍結(jié)的位置參數(shù);
keywords:要凍結(jié)的關(guān)鍵字參數(shù)。
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])更新一個(gè)包裹(wrapper)函數(shù),使其看起來(lái)更像被包裹(wrapped)的函數(shù)(即把 被封裝函數(shù)的__name__、__module__、__doc__和 __dict__都復(fù)制到封裝函數(shù)去。wraps是通過partial與update_wrapper實(shí)現(xiàn)的。
通常,經(jīng)由被裝飾(decorator)的函數(shù)會(huì)表現(xiàn)為另外一個(gè)函數(shù)了(函數(shù)名、說明等都變?yōu)榱搜b飾器的);通過wraps函數(shù)可以消除裝飾器的這些副作用。
def wrapper_decorator(func): @functools.wraps(func) # 若是去掉此wraps,則被裝飾的函數(shù)名稱與說明都變?yōu)榇撕瘮?shù)的 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將普通函數(shù)轉(zhuǎn)換為泛型函數(shù),而singledispatchmethod(3.8引入)將類方法轉(zhuǎn)換為泛型函數(shù):
泛型函數(shù):是指由多個(gè)函數(shù)(針對(duì)不同類型的實(shí)現(xiàn))組成的函數(shù),調(diào)用時(shí)由分派算法決定使用哪個(gè)實(shí)現(xiàn);
Single dispatch:一種泛型函數(shù)分派形式,基于第一個(gè)參數(shù)的類型來(lái)決定;
dispatch使用:
singledispatch裝飾dispatch的基函數(shù)base_fun(即,注冊(cè)object類型);
注冊(cè)后續(xù)分發(fā)函數(shù)使用裝飾器@{base_fun}.register({type}),注冊(cè)每種需要特殊處理的類型;
分發(fā)函數(shù)名稱無(wú)關(guān)緊要,_是個(gè)不錯(cuò)的選擇;
可以疊放多個(gè)register裝飾器,讓同一個(gè)函數(shù)支持多種類型;
# 缺省匹配類型,注冊(cè)object類型(與后續(xù)注冊(cè)類型都不匹配時(shí)使用) @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") ### 打印注冊(cè)的類型: # 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()用來(lái)自定義排序規(guī)則,可將比較函數(shù)(comparison function)轉(zhuǎn)化為關(guān)鍵字函數(shù)(key function):
比較函數(shù):接受兩個(gè)參數(shù),比較這兩個(gè)參數(shù),并返回0、1或-1;
關(guān)鍵字函數(shù):接受一個(gè)參數(shù),返回其對(duì)應(yīng)的可比較對(duì)象;
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]
是一個(gè)類裝飾器,用于自動(dòng)實(shí)現(xiàn)類的比較運(yùn)算;類定義一個(gè)或者多個(gè)比較排序方法,類裝飾器將會(huì)補(bǔ)充其余的比較方法。
被修飾的類必須至少定義 __lt__(), __le__(),__gt__(),__ge__()中的一個(gè),以及__eq__()方法。
如,只需定義lt與eq方法,即可實(shí)現(xiàn)所有比較:
@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)
到此,相信大家對(duì)“python高階函數(shù)functools模塊如何使用”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。