Python中functools模組函式解析
Python自帶的 functools 模組提供了一些常用的高階函式,也就是用於處理其它函式的特殊函式。換言之,就是能使用該模組對可呼叫物件進行處理。
functools模組函式概覽
- functools.cmp_to_key(func)
- functools.total_ordering(cls)
- functools.reduce(function, iterable[, initializer])
- functools.partial(func[, args][, *keywords])
- functools.update_wrapper(wrapper, wrapped[, assigned][, updated])
- functools.wraps(wrapped[, assigned][, updated])
functools.cmp_to_key()
語法:
functools.cmp_to_key(func)
該函式用於將舊式的比較函式轉換為關鍵字函式。
舊式的比較函式:接收兩個引數,返回比較的結果。返回值小於零則前者小於後者,返回值大於零則相反,返回值等於零則兩者相等。
關鍵字函式:接收一個引數,返回其對應的可比較物件。例如 sorted(), min(), max(), heapq.nlargest(), heapq.nsmallest(), itertools.groupby() 都可作為關鍵字函式。
在 Python 3 中,有很多地方都不再支援舊式的比較函式,此時可以使用 cmp_to_key() 進行轉換。
示例:
sorted(iterable, key=cmp_to_key(cmp_func))
functools.total_ordering()
語法:
functools.total_ordering(cls)
這是一個類裝飾器,用於自動實現類的比較運算。
我們只需要在類中實現 __eq__() 方法和以下方法中的任意一個 __lt__(), __le__(), __gt__(), __ge__(),那麼 total_ordering() 就能自動幫我們實現餘下的幾種比較運算。
示例:
@total_ordering class Student: def __eq__(self, other): return ((self.lastname.lower(), self.firstname.lower()) == (other.lastname.lower(), other.firstname.lower())) def __lt__(self, other): return ((self.lastname.lower(), self.firstname.lower()) < (other.lastname.lower(), other.firstname.lower()))
functools.reduce()
語法:
functools.reduce(function, iterable[, initializer])
該函式與 Python 內建的 reduce() 函式相同,主要用於編寫相容 Python 3 的程式碼。
functools.partial()
語法:
functools.partial(func[, *args][, **keywords])
該函式返回一個 partial 物件,呼叫該物件的效果相當於呼叫 func 函式,並傳入位置引數 args 和關鍵字引數 keywords 。如果呼叫該物件時傳入了位置引數,則這些引數會被新增到 args 中。如果傳入了關鍵字引數,則會被新增到 keywords 中。
partial() 函式的等價實現大致如下:
def partial(func, *args, **keywords): def newfunc(*fargs, **fkeywords): newkeywords = keywords.copy() newkeywords.update(fkeywords) return func(*(args + fargs), **newkeywords) newfunc.func = func newfunc.args = args newfunc.keywords = keywords return newfunc
partial() 函式主要用於“凍結”某個函式的部分引數,返回一個引數更少、使用更簡單的函式物件。
示例:
>>> from functools import partial >>> basetwo = partial(int, base=2) >>> basetwo.__doc__ = 'Convert base 2 string to an int.' >>> basetwo('10010') 18
functools.update_wrapper()
語法:
functools.update_wrapper(wrapper, wrapped[, assigned][, updated])
該函式用於更新包裝函式(wrapper),使它看起來像原函式一樣。可選的引數是一個元組,assigned 元組指定要直接使用原函式的值進行替換的屬性,updated 元組指定要對照原函式進行更新的屬性。這兩個引數的預設值分別是模組級別的常量:WRAPPER_ASSIGNMENTS 和 WRAPPER_UPDATES。前者指定了對包裝函式的 __name__, __module__, __doc__ 屬性進行直接賦值,而後者指定了對包裝函式的 __dict__ 屬性進行更新。
該函式主要用於裝飾器函式的定義中,置於包裝函式之前。如果沒有對包裝函式進行更新,那麼被裝飾後的函式所具有的元資訊就會變為包裝函式的元資訊,而不是原函式的元資訊。
functools.wraps()
語法:
functools.wraps(wrapped[, assigned][, updated])
wraps() 簡化了 update_wrapper() 函式的呼叫。它等價於 partial(update_wrapper, wrapped=wrapped, assigned, updated=updated)。
示例:
>>> from functools import wraps >>> def my_decorator(f): ... @wraps(f) ... def wrapper(*args, **kwds): ... print 'Calling decorated function' ... return f(*args, **kwds) ... return wrapper >>> @my_decorator ... def example(): ... """Docstring""" ... print 'Called example function' >>> example() Calling decorated function Called example function >>> example.__name__ 'example' >>> example.__doc__ 'Docstring'
如果不使用這個函式,示例中的函式名就會變成 wrapper ,並且原函式 example() 的說明文件(docstring)就會丟失。