python中的functools模块
functools模塊可以作用于所有的可以被調(diào)用的對(duì)象,包括函數(shù) 定義了__call__方法的類(lèi)等
1 functools.cmp_to_key(func)
將比較函數(shù)(接受兩個(gè)參數(shù),通過(guò)比較兩個(gè)參數(shù)的大小返回負(fù)值,0,或者正數(shù))轉(zhuǎn)換為key function(返回一個(gè)值用來(lái)比較或者排序的可調(diào)用對(duì)象),
例如: sorted(iterable, functools.cmp_to_key(locale.strcoll))
def cmp1(n1, n2):return n1 - n2a = [1, 6, 2, 9] print(sorted(a, key=functools.cmp_to_key(cmp1)))2 @functools.lru_cache(maxsize=128, typed=False)
首先這是一個(gè)裝飾器
其次,介紹一下LRU算法:
LRU是最常用的緩存算法,全稱(chēng)叫“Least Recently Used”,顧名思義,就是在緩存miss 并且緩存空間已滿(mǎn)的時(shí)候,將最久沒(méi)訪(fǎng)問(wèn)過(guò)的數(shù)據(jù)刪除從而騰出空間。
然后,說(shuō)一下這個(gè)裝飾器的兩個(gè)參數(shù)的含義:
maxsize: 表示緩存大小,如果設(shè)置為None,表示不限制,設(shè)置為0表示不啟用緩存機(jī)制
typed:如果設(shè)置為T(mén)rue,則該裝飾器所裝飾的函數(shù)的參數(shù)即使值相等(比如說(shuō) 3 == 3.0 ),但類(lèi)型不同(一個(gè)是整型一個(gè)是浮點(diǎn)),也會(huì)被區(qū)分對(duì)待為不同的緩存
然后,說(shuō)明一下這個(gè)裝飾器對(duì)所裝飾的函數(shù)的要求,
1 函數(shù)的參數(shù)接收的值必須是不可變對(duì)象,像字符串,數(shù)字,元組等都屬于此列
2 其次函數(shù)返回的對(duì)象最好也是不可變對(duì)象,當(dāng)然這一點(diǎn)沒(méi)有硬性要求,但是道理大家懂。
來(lái)一個(gè)栗子:
@functools.lru_cache(2526) def get_resource(page):url = "https://urls_does_not_contain_pornographic_informations/%s" % pagetry:with urllib.request.urlopen(url) as s:return s.read()except urllib.error.HTTPError:return 'Not Found'for i in range(1, 2526):pep = get_resource(i)print(pep)3 @functools.total_ordering
首先這是一個(gè)類(lèi)裝飾器,這個(gè)類(lèi)裝飾器要求它所定義的類(lèi)中必須定義:
1??小于__lt__(), 小于等于__le__(),大于__gt__(),大于等于__ge__()中的一個(gè)
2??還要定義等于__eq__()方法。
只要我們按照要求定義了這些方法,該裝飾器就會(huì)為我們完成其余的比較排序方法?。
4?functools.partial(func, *args, **keywords)
?類(lèi)似于這樣:
def abc(a, b):print a + bdef partial(func, *args, **kwargs):args_li = list(args)def inner(*nargs, **nkwargs):args_li.extend(nargs)kwargs.update(nkwargs)return func(*args_li, **kwargs)return innernew_abc = partial(abc, 2)new_abc(4)實(shí)際上就是給某個(gè)函數(shù)加上幾個(gè)固定參數(shù)然后返回一個(gè)新的函數(shù),對(duì)于多個(gè)對(duì)象更新相同的值來(lái)說(shuō)可以用到。比如:
from functools import partialclass Test(object):def __init__(self):self.name = "lala"self.age = 20def _update_attr(obj, update_dic):map(lambda item: setattr(obj, item[0], item[1]), update_dic.iteritems())update_attr = partial(_update_attr, update_dic={"name": "mncu", "age": 18})test_obj_list = [Test() for i in xrange(20)]map(update_attr, test_obj_list)for test_obj in test_obj_list:print test_obj.name, test_obj.age? 5?class functools.partialmethod(func, *args, **keywords)
作用類(lèi)似于上面的partial函數(shù),但這個(gè)方法作用于類(lèi)的方法,返回的是方法而不是函數(shù)。
>>> 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 = partialmethod(set_state, True) ... set_dead = partialmethod(set_state, False) ... >>> c = Cell() >>> c.alive False >>> c.set_alive() >>> c.alive True? 6?functool.update_wrapper(wrapper, wrapped[, assigned][, updated])
? ? functools.wraps(wrapped[, assigned][, updated])
在python中,當(dāng)一個(gè)函數(shù)被裝飾器裝飾后,這個(gè)函數(shù)名字對(duì)應(yīng)的函數(shù)對(duì)象實(shí)際上是那個(gè)裝飾器函數(shù),也就是該函數(shù)名對(duì)應(yīng)的的__name__以及__doc__實(shí)際上已經(jīng)改變了,這就導(dǎo)致很難調(diào)試。而update_wrapper以及wraps就是用來(lái)解決這個(gè)問(wèn)題。
#!/usr/bin/env python # encoding: utf-8def wrap(func):def call_it(*args, **kwargs):"""wrap func: call_it"""print 'before call'return func(*args, **kwargs)return call_it@wrap def hello():"""say hello"""print 'hello world'from functools import update_wrapper def wrap2(func):def call_it(*args, **kwargs):"""wrap func: call_it2"""print 'before call'return func(*args, **kwargs)return update_wrapper(call_it, func)@wrap2 def hello2():"""test hello"""print 'hello world2'if __name__ == '__main__':hello()print hello.__name__print hello.__doc__printhello2()print hello2.__name__print hello2.__doc__結(jié)果:
before call
hello world
call_it
wrap func: call_it
before call
hello world2
hello2
test hello
結(jié)果:
before call
hello world3
hello3
test hello 3
?
參考:
https://blog.theerrorlog.com/simple-lru-cache-in-python-3.html, 作者:?Kay Zheng??
http://www.wklken.me/posts/2013/08/18/python-extra-functools.html? 作者:WKLKEN?
?
轉(zhuǎn)載于:https://www.cnblogs.com/MnCu8261/p/8763552.html
總結(jié)
以上是生活随笔為你收集整理的python中的functools模块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 十六、python沉淀之路--迭代器
- 下一篇: ZOJ 3879(大模拟)