日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)Python教程:functools—-高階函數(shù)和可調(diào)用對象上的操作

functools —- 高階函數(shù)和可調(diào)用對象上的操作

源代碼: Lib/functools.py

創(chuàng)新互聯(lián)-云計算及IDC服務提供商,涵蓋公有云、IDC機房租用、服務器托管、等保安全、私有云建設等企業(yè)級互聯(lián)網(wǎng)基礎(chǔ)服務,咨詢熱線:18980820575


functools 模塊應用于高階函數(shù),即參數(shù)或(和)返回值為其他函數(shù)的函數(shù)。 通常來說,此模塊的功能適用于所有可調(diào)用對象。

functools 模塊定義了以下函數(shù):

@functools.cache(user_function)

簡單輕量級未綁定函數(shù)緩存。 有時稱為 “memoize”。

返回值與 lru_cache(maxsize=None) 相同,創(chuàng)建一個查找函數(shù)參數(shù)的字典的簡單包裝器。 因為它不需要移出舊值,所以比帶有大小限制的 lru_cache() 更小更快。

例如:

 
 
 
 
  1. @cache
  2. def factorial(n):
  3. return n * factorial(n-1) if n else 1
  4. >>> factorial(10) # no previously cached result, makes 11 recursive calls
  5. 3628800
  6. >>> factorial(5) # just looks up cached value result
  7. 120
  8. >>> factorial(12) # makes two new recursive calls, the other 10 are cached
  9. 479001600

3.9 新版功能.

@functools.cached_property(func)

將一個類方法轉(zhuǎn)換為特征屬性,一次性計算該特征屬性的值,然后將其緩存為實例生命周期內(nèi)的普通屬性。 類似于 property() 但增加了緩存功能。 對于在其他情況下實際不可變的高計算資源消耗的實例特征屬性來說該函數(shù)非常有用。

示例:

 
 
 
 
  1. class DataSet:
  2. def __init__(self, sequence_of_numbers):
  3. self._data = tuple(sequence_of_numbers)
  4. @cached_property
  5. def stdev(self):
  6. return statistics.stdev(self._data)

cached_property() 的設定與 property() 有所不同。 常規(guī)的 property 會阻止屬性寫入,除非定義了 setter。 與之相反,cached_property 則允許寫入。

cached_property 裝飾器僅在執(zhí)行查找且不存在同名屬性時才會運行。 當運行時,cached_property 會寫入同名的屬性。 后續(xù)的屬性讀取和寫入操作會優(yōu)先于 cached_property 方法,其行為就像普通的屬性一樣。

緩存的值可通過刪除該屬性來清空。 這允許 cached_property 方法再次運行。

注意,這個裝飾器會影響 PEP 412 鍵共享字典的操作。 這意味著相應的字典實例可能占用比通常時更多的空間。

而且,這個裝飾器要求每個實例上的 __dict__ 是可變的映射。 這意味著它將不適用于某些類型,例如元類(因為類型實例上的 __dict__ 屬性是類命名空間的只讀代理),以及那些指定了 __slots__ 但未包括 __dict__ 作為所定義的空位之一的類(因為這樣的類根本沒有提供 __dict__ 屬性)。

如果可變的映射不可用或者如果想要節(jié)省空間的鍵共享,可以通過在 cache() 之上堆疊一個 property() 來實現(xiàn)類似 cached_property() 的效果:

 
 
 
 
  1. class DataSet:
  2. def __init__(self, sequence_of_numbers):
  3. self._data = sequence_of_numbers
  4. @property
  5. @cache
  6. def stdev(self):
  7. return statistics.stdev(self._data)

3.8 新版功能.

functools.cmp_to_key(func)

將(舊式的)比較函數(shù)轉(zhuǎn)換為新式的 key function . 在類似于 sorted() , min() , max() , heapq.nlargest() , heapq.nsmallest() , itertools.groupby() 等函數(shù)的 key 參數(shù)中使用。此函數(shù)主要用作將 python 2 程序轉(zhuǎn)換至新版的轉(zhuǎn)換工具,以保持對比較函數(shù)的兼容。

A comparison function is any callable that accepts two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than. A key function is a callable that accepts one argument and returns another value to be used as the sort key.

示例:

 
 
 
 
  1. sorted(iterable, key=cmp_to_key(locale.strcoll)) # locale-aware sort order

有關(guān)排序示例和簡要排序教程,請參閱 排序指南 。

3.2 新版功能.

@functools.lru_cache(user_function)

@functools.lru_cache(maxsize=128, typed=False)

一個為函數(shù)提供緩存功能的裝飾器,緩存 maxsize 組傳入?yún)?shù),在下次以相同參數(shù)調(diào)用時直接返回上一次的結(jié)果。用以節(jié)約高開銷或I/O函數(shù)的調(diào)用時間。

由于使用了字典存儲緩存,所以該函數(shù)的固定參數(shù)和關(guān)鍵字參數(shù)必須是可哈希的。

Distinct argument patterns may be considered to be distinct calls with separate cache entries. For example, f(a=1, b=2) and f(b=2, a=1) differ in their keyword argument order and may have two separate cache entries.

如果指定了 user_function,它必須是一個可調(diào)用對象。 這允許 lru_cache 裝飾器被直接應用于一個用戶自定義函數(shù),讓 maxsize 保持其默認值 128:

 
 
 
 
  1. @lru_cache
  2. def count_vowels(sentence):
  3. return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou')

如果 maxsize 設為 None,LRU 特性將被禁用且緩存可無限增長。

如果 typed 被設置為 true ,不同類型的函數(shù)參數(shù)將被分別緩存。 如果 typed 為 false ,實現(xiàn)通常會將它們視為等價的調(diào)用,只緩存一個結(jié)果。(有些類型,如 strint ,即使 typed 為 false ,也可能被分開緩存)。

注意,類型的特殊性只適用于函數(shù)的直接參數(shù)而不是它們的內(nèi)容。 標量參數(shù) Decimal(42)Fraction(42) 被視為具有不同結(jié)果的不同調(diào)用。相比之下,元組參數(shù) ('answer', Decimal(42))('answer', Fraction(42)) 被視為等同的。

被包裝的函數(shù)配有一個 cache_parameters() 函數(shù),該函數(shù)返回一個新的 dict 用來顯示 maxsizetyped 的值。 這只是出于顯示信息的目的。 改變值沒有任何效果。

為了幫助衡量緩存的有效性以及調(diào)整 maxsize 形參,被包裝的函數(shù)會帶有一個 cache_info() 函數(shù),它返回一個 named tuple 以顯示 hits, misses, maxsizecurrsize

該裝飾器也提供了一個用于清理/使緩存失效的函數(shù) cache_clear() 。

原始的未經(jīng)裝飾的函數(shù)可以通過 __wrapped__ 屬性訪問。它可以用于檢查、繞過緩存,或使用不同的緩存再次裝飾原始函數(shù)。

緩存會保持對參數(shù)的引用并返回值,直到它們結(jié)束生命期退出緩存或者直到緩存被清空。

If a method is cached, the self instance argument is included in the cache. See 我該如何緩存方法調(diào)用?

LRU(最久未使用算法)緩存) 在最近的調(diào)用是即將到來的調(diào)用的最佳預測值時性能最好(例如,新聞服務器上最熱門文章傾向于每天更改)。 緩存的大小限制可確保緩存不會在長期運行進程如網(wǎng)站服務器上無限制地增長。

一般來說,LRU緩存只在當你想要重用之前計算的結(jié)果時使用。因此,用它緩存具有副作用的函數(shù)、需要在每次調(diào)用時創(chuàng)建不同、易變的對象的函數(shù)或者諸如time()或random()之類的不純函數(shù)是沒有意義的。

靜態(tài) Web 內(nèi)容的 LRU 緩存示例:

 
 
 
 
  1. @lru_cache(maxsize=32)
  2. def get_pep(num):
  3. 'Retrieve text of a Python Enhancement Proposal'
  4. resource = 'https://peps.python.org/pep-%04d/' % num
  5. try:
  6. with urllib.request.urlopen(resource) as s:
  7. return s.read()
  8. except urllib.error.HTTPError:
  9. return 'Not Found'
  10. >>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
  11. ... pep = get_pep(n)
  12. ... print(n, len(pep))
  13. >>> get_pep.cache_info()
  14. CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)

以下是使用緩存通過 動態(tài)規(guī)劃 計算 斐波那契數(shù)列 的例子。

 
 
 
 
  1. @lru_cache(maxsize=None)
  2. def fib(n):
  3. if n < 2:
  4. return n
  5. return fib(n-1) + fib(n-2)
  6. >>> [fib(n) for n in range(16)]
  7. [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
  8. >>> fib.cache_info()
  9. CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

3.2 新版功能.

在 3.3 版更改: 添加 typed 選項。

在 3.8 版更改: 添加了 user_function 選項。

3.9 新版功能: 新增函數(shù) cache_parameters()

@functools.total_ordering

給定一個聲明一個或多個全比較排序方法的類,這個類裝飾器實現(xiàn)剩余的方法。這減輕了指定所有可能的全比較操作的工作。

此類必須包含以下方法之一:__lt__() 、__le__()__gt__()__ge__()。另外,此類必須支持 __eq__() 方法。

例如:

 
 
 
 
  1. @total_ordering
  2. class Student:
  3. def _is_valid_operand(self, other):
  4. return (hasattr(other, "lastname") and
  5. hasattr(other, "firstname"))
  6. def __eq__(self, other):
  7. if not self._is_valid_operand(other):
  8. return NotImplemented
  9. return ((self.lastname.lower(), self.firstname.lower()) ==
  10. (other.lastname.lower(), other.firstname.lower()))
  11. def __lt__(self, other):
  12. if not self._is_valid_operand(other):
  13. return NotImplemented
  14. return ((self.lastname.lower(), self.firstname.lower()) <
  15. (other.lastname.lower(), other.firstname.lower()))

備注

雖然此裝飾器使得創(chuàng)建具有良好行為的完全有序類型變得非常容易,但它 確實 是以執(zhí)行速度更緩慢和派生比較方法的堆?;厮莞鼜碗s為代價的。 如果性能基準測試表明這是特定應用的瓶頸所在,則改為實現(xiàn)全部六個富比較方法應該會輕松提升速度。

備注

這個裝飾器不會嘗試重載類 或其上級類 中已經(jīng)被聲明的方法。 這意味著如果某個上級類定義了比較運算符,則 total_ordering 將不會再次實現(xiàn)它,即使原方法是抽象方法。

3.2 新版功能.

在 3.4 版更改: 現(xiàn)在已支持從未識別類型的下層比較函數(shù)返回 NotImplemented 異常。

functools.partial(func, /, \args, **keywords*)

返回一個新的 部分對象,當被調(diào)用時其行為類似于 func 附帶位置參數(shù) args 和關(guān)鍵字參數(shù) keywords 被調(diào)用。 如果為調(diào)用提供了更多的參數(shù),它們會被附加到 args。 如果提供了額外的關(guān)鍵字參數(shù),它們會擴展并重載 keywords。 大致等價于:

 
 
 
 
  1. def partial(func, /, *args, **keywords):
  2. def newfunc(*fargs, **fkeywords):
  3. newkeywords = {**keywords, **fkeywords}
  4. return func(*args, *fargs, **newkeywords)
  5. newfunc.func = func
  6. newfunc.args = args
  7. newfunc.keywords = keywords
  8. return newfunc

partial() 會被“凍結(jié)了”一部分函數(shù)參數(shù)和/或關(guān)鍵字的部分函數(shù)應用所使用,從而得到一個具有簡化簽名的新對象。 例如,partial() 可用來創(chuàng)建一個行為類似于 int() 函數(shù)的可調(diào)用對象,其中 base 參數(shù)默認為二:

 
 
 
 
  1. >>> from functools import partial
  2. >>> basetwo = partial(int, base=2)
  3. >>> basetwo.__doc__ = 'Convert base 2 string to an int.'
  4. >>> basetwo('10010')
  5. 18

class functools.partialmethod(func, /, \args, **keywords*)

返回一個新的 partialmethod 描述器,其行為類似 partial 但它被設計用作方法定義而非直接用作可調(diào)用對象。

func 必須是一個 descriptor 或可調(diào)用對象(同屬兩者的對象例如普通函數(shù)會被當作描述器來處理)。

func 是一個描述器(例如普通 Python 函數(shù), classmethod(), staticmethod(), abstractmethod() 或其他 partialmethod 的實例)時, 對 __get__ 的調(diào)用會被委托給底層的描述器,并會返回一個適當?shù)?部分對象 作為結(jié)果。

func 是一個非描述器類可調(diào)用對象時,則會動態(tài)創(chuàng)建一個適當?shù)慕壎ǚ椒ā?當用作方法時其行為類似普通 Python 函數(shù):將會插入 self 參數(shù)作為第一個位置參數(shù),其位置甚至會處于提供給 partialmethod 構(gòu)造器的 argskeywords 之前。

示例:

 
 
 
 
  1. >>> class Cell:
  2. ... def __init__(self):
  3. ... self._alive = False
  4. ... @property
  5. ... def alive(self):
  6. ... return self._alive
  7. ... def set_state(self, state):
  8. ... self._alive = bool(state)
  9. ... set_alive = partialmethod(set_state, True)
  10. ... set_dead = partialmethod(set_state, False)
  11. ...
  12. >>> c = Cell()
  13. >>> c.alive
  14. False
  15. >>> c.set_alive()
  16. >>> c.alive
  17. True

3.4 新版功能.

functools.reduce(function, iterable[, initializer])

將兩個參數(shù)的 function 從左至右積累地應用到 iterable 的條目,以便將該可迭代對象縮減為單一的值。 例如,reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 是計算 ((((1+2)+3)+4)+5) 的值。 左邊的參數(shù) x 是積累值而右邊的參數(shù) y 則是來自 iterable 的更新值。 如果存在可選項 initializer,它會被放在參與計算的可迭代對象的條目之前,并在可迭代對象為空時作為默認值。 如果沒有給出 initializer 并且 iterable 僅包含一個條目,則將返回第一項。

大致相當于:

 
 
 
 
  1. def reduce(function, iterable, initializer=None):
  2. it = iter(iterable)
  3. if initializer is None:
  4. value = next(it)
  5. else:
  6. value = initializer
  7. for element in it:
  8. value = function(value, element)
  9. return value

請參閱 itertools.accumulate() 了解有關(guān)可產(chǎn)生所有中間值的迭代器。

@functools.singledispatch

將一個函數(shù)轉(zhuǎn)換為 單分派 generic function。

要定義一個泛型函數(shù),用裝飾器 @singledispatch 來裝飾它。當使用 @singledispatch 定義一個函數(shù)時,請注意調(diào)度發(fā)生在第一個參數(shù)的類型上:

 
 
 
 
  1. >>> from functools import singledispatch
  2. >>> @singledispatch
  3. ... def fun(arg, verbose=False):
  4. ... if verbose:
  5. ... print("Let me just say,", end=" ")
  6. ... print(arg)

要將重載的實現(xiàn)添加到函數(shù)中,請使用泛型函數(shù)的 register() 屬性,它可以被用作裝飾器。 對于帶有類型標注的函數(shù),該裝飾器將自動推斷第一個參數(shù)的類型:

 
 
 
 
  1. >>> @fun.register
  2. ... def _(arg: int, verbose=False):
  3. ... if verbose:
  4. ... print("Strength in numbers, eh?", end=" ")
  5. ... print(arg)
  6. ...
  7. >>> @fun.register
  8. ... def _(arg: list, verbose=False):
  9. ... if verbose:
  10. ... print("Enumerate this:")
  11. ... for i, elem in enumerate(arg):
  12. ... print(i, elem)

types.UnionType and typing.Union can also be used:

 
 
 
 
  1. >>> @fun.register
  2. ... def _(arg: int | float, verbose=False):
  3. ... if verbose:
  4. ... print("Strength in numbers, eh?", end=" ")
  5. ... print(arg)
  6. ...
  7. >>> from typing import Union
  8. >>> @fun.register
  9. ... def _(arg: Union[list, set], verbose=False):
  10. ... if verbose:
  11. ... print("Enumerate this:")
  12. ... for i, elem in enumerate(arg):
  13. ... print(i, elem)
  14. ...

對于不使用類型標注的代碼,可以將適當?shù)念愋蛥?shù)顯式地傳給裝飾器本身:

 
 
 
 
  1. >>> @fun.register(complex)
  2. ... def _(arg, verbose=False):
  3. ... if verbose:
  4. ... print("Better than complicated.", end=" ")
  5. ... print(arg.real, arg.imag)
  6. ...

要啟用注冊 lambda 和現(xiàn)有的函數(shù),也可以使用 register() 屬性的函數(shù)形式:

 
 
 
 
  1. >>> def nothing(arg, verbose=False):
  2. ... print("Nothing.")
  3. ...
  4. >>> fun.register(type(None), nothing)

register() 屬性會返回未被裝飾的函數(shù)。 這將啟用裝飾器棧、封存,并為每個變量單獨創(chuàng)建單元測試:

 
 
 
 
  1. >>> @fun.register(float)
  2. ... @fun.register(Decimal)
  3. ... def fun_num(arg, verbose=False):
  4. ... if verbose:
  5. ... print("Half of your number:", end=" ")
  6. ... print(arg / 2)
  7. ...
  8. >>> fun_num is fun
  9. False

在調(diào)用時,泛型函數(shù)會根據(jù)第一個參數(shù)的類型進行分派:

 
 
 
 
  1. >>> fun("Hello, world.")
  2. Hello, world.
  3. >>> fun("test.", verbose=True)
  4. Let me just say, test.
  5. >>> fun(42, verbose=True)
  6. Strength in numbers, eh? 42
  7. >>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True)
  8. Enumerate this:
  9. 0 spam
  10. 1 spam
  11. 2 eggs
  12. 3 spam
  13. >>> fun(None)
  14. Nothing.
  15. >>> fun(1.23)
  16. 0.615

在沒有針對特定類型的已注冊實現(xiàn)的情況下,會使用其方法解析順序來查找更通用的實現(xiàn)。 使用 @singledispatch 裝飾的原始函數(shù)將為基本的 object 類型進行注冊,這意味著它將在找不到更好的實現(xiàn)時被使用。

如果一個實現(xiàn)被注冊到 abstract base class,則基類的虛擬子類將被發(fā)送到該實現(xiàn):

 
 
 
 
  1. >>> from collections.abc import Mapping
  2. >>> @fun.register
  3. ... def _(arg: Mapping, verbose=False):
  4. ... if verbose:
  5. ... print("Keys & Values")
  6. ... for key, value in arg.items():
  7. ... print(key, "=>", value)
  8. ...
  9. >>> fun({"a": "b"})
  10. a => b

要檢查泛型函數(shù)將為給定的類型選擇哪個實現(xiàn),請使用 dispatch() 屬性:

 
 
 
 
  1. >>> fun.dispatch(float)
  2. >>> fun.dispatch(dict) # note: default implementation

要訪問所有已注冊實現(xiàn),請使用只讀的 registry 屬性:

 
 
 
 
  1. >>> fun.registry.keys()
  2. dict_keys([, , ,
  3. , ,
  4. ])
  5. >>> fun.registry[float]
  6. >>> fun.registry[object]

3.4 新版功能.

在 3.7 版更改: register() 屬性現(xiàn)在支持使用類型標注。

在 3.11 版更改: The register() attribute now supports types.UnionType and typing.Union as type annotations.

class functools.singledispatchmethod(func)

將一個方法轉(zhuǎn)換為 單分派 generic function。

要定義一個泛型方法,請用 @singledispatchmethod 裝飾器來裝飾它。 當使用 @singledispatchmethod 定義一個函數(shù)時,請注意發(fā)送操作將針對第一個非 self 或非 cls 參數(shù)的類型上:

 
 
 
 
  1. class Negator:
  2. @singledispatchmethod
  3. def neg(self, arg):
  4. raise NotImplementedError("Cannot negate a")
  5. @neg.register
  6. def _(self, arg: int):
  7. return -arg
  8. @neg.register
  9. def _(self, arg: bool):
  10. return not arg

@singledispatchmethod 支持與其他裝飾器如 @classmethod 相嵌套。 請注意為了允許 dispatcher.register,singledispatchmethod 必須是 最外層的 裝飾器。 下面是一個 Negator 類包含綁定到類的 neg 方法,而不是一個類實例:

 
 
 
 
  1. class Negator:
  2. @singledispatchmethod
  3. @classmethod
  4. def neg(cls, arg):
  5. raise NotImplementedError("Cannot negate a")
  6. @neg.register
  7. @classmethod
  8. def _(cls, arg: int):
  9. return -arg
  10. @neg.register
  11. @classmethod
  12. def _(cls, arg: bool):
  13. return not arg

同樣的模式也可被用于其他類似的裝飾器: @staticmethod, @abstractmethod 等等。

3.8 新版功能.

functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)

更新一個 wrapper 函數(shù)以使其類似于 wrapped 函數(shù)。 可選參數(shù)為指明原函數(shù)的哪些屬性要直接被賦值給 wrapper 函數(shù)的匹配屬性的元組,并且這些 wrapper 函數(shù)的屬性將使用原函數(shù)的對應屬性來更新。 這些參數(shù)的默認值是模塊級常量 WRAPPER_ASSIGNMENTS (它將被賦值給 wrapper 函數(shù)的 __module__, __name__, __qualname__, __annotations____doc__ 即文檔字符串) 以及 WRAPPER_UPDATES (它將更新 wrapper 函數(shù)的 __dict__ 即實例字典)。

為了允許出于內(nèi)省和其他目的訪問原始函數(shù)(例如繞過 lru_cache() 之類的緩存裝飾器),此函數(shù)會自動為 wrapper 添加一個指向被包裝函數(shù)的 __wrapped__ 屬性。

此函數(shù)的主要目的是在 decorator 函數(shù)中用來包裝被裝飾的函數(shù)并返回包裝器。 如果包裝器函數(shù)未被更新,則被返回函數(shù)的元數(shù)據(jù)將反映包裝器定義而不是原始函數(shù)定義,這通常沒有什么用處。

update_wrapper() 可以與函數(shù)之外的可調(diào)用對象一同使用。 在 assignedupdated 中命名的任何屬性如果不存在于被包裝對象則會被忽略(即該函數(shù)將不會嘗試在包裝器函數(shù)上設置它們)。 如果包裝器函數(shù)自身缺少在 updated 中命名的任何屬性則仍將引發(fā) AttributeError。

3.2 新版功能: 自動添加 __wrapped__ 屬性。

3.2 新版功能: 默認拷貝 __annotations__ 屬性。

在 3.2 版更改: 不存在的屬性將不再觸發(fā) AttributeError。

在 3.4 版更改: __wrapped__ 屬性現(xiàn)在總是指向被包裝的函數(shù),即使該函數(shù)定義了 __wrapped__ 屬性。 (參見 bpo-17482)

@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)

這是一個便捷函數(shù),用于在定義包裝器函數(shù)時發(fā)起調(diào)用 update_wrapper() 作為函數(shù)裝飾器。 它等價于 partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)。 例如:

 
 
 
 
  1. >>> from functools import wraps
  2. >>> def my_decorator(f):
  3. ... @wraps(f)
  4. ... def wrapper(*args, **kwds):
  5. ... print('Calling decorated function')
  6. ... return f(*args, **kwds)
  7. ... return wrapper
  8. ...
  9. >>> @my_decorator
  10. ... def example():
  11. ... """Docstring"""
  12. ... print('Called example function')
  13. ...
  14. >>> example()
  15. Calling decorated function
  16. Called example function
  17. >>> example.__name__
  18. 'example'
  19. >>> example.__doc__
  20. 'Docstring'

如果不使用這個裝飾器工廠函數(shù),則 example 函數(shù)的名稱將變?yōu)?'wrapper',并且 example() 原本的文檔字符串將會丟失。

partial 對象

partial 對象是由 partial() 創(chuàng)建的可調(diào)用對象。 它們具有三個只讀屬性:

partial.func

一個可調(diào)用對象或函數(shù)。 對 partial 對象的調(diào)用將被轉(zhuǎn)發(fā)給 func 并附帶新的參數(shù)和關(guān)鍵字。

partial.args

最左邊的位置參數(shù)將放置在提供給 partial 對象調(diào)用的位置參數(shù)之前。

partial.keywords

當調(diào)用 partial 對象時將要提供的關(guān)鍵字參數(shù)。

partial 對象與 function 對象的類似之處在于它們都是可調(diào)用、可弱引用的對象并可擁有屬性。 但兩者也存在一些重要的區(qū)別。 例如前者不會自動創(chuàng)建 __name__ 和 __doc__ 屬性。 而且,在類中定義的 partial 對象的行為類似于靜態(tài)方法,并且不會在實例屬性查找期間轉(zhuǎn)換為綁定方法。


文章題目:創(chuàng)新互聯(lián)Python教程:functools—-高階函數(shù)和可調(diào)用對象上的操作
網(wǎng)站地址:http://www.5511xx.com/article/cojsoie.html