python 重载的实现(single-dispatch generic function)
DAY 11. python 重載
函數(shù)重載是指允許定義參數(shù)數(shù)量或類型不同的同名函數(shù),程序在運(yùn)行時會根據(jù)所傳遞的參數(shù)類型選擇應(yīng)該調(diào)用的函數(shù)
,但在默認(rèn)情況下,python是不支持函數(shù)重載的,定義同名函數(shù)會發(fā)生覆蓋
至于不支持的原因,我想大概是沒必要,首先,只在兩種情況下可能發(fā)生函數(shù)重載,一是參數(shù)類型不同,二是參數(shù)個數(shù)不同,對于第一種情況,鴨子類型的存在使得函數(shù)不在乎參數(shù)類型而只關(guān)心參數(shù)的行為,所以你可以傳遞任何類型的參數(shù),對于第二種情況,缺省參數(shù)的使用使得可以傳遞任意多個參數(shù),因此函數(shù)的重載在python中就顯得很雞肋了,但如果非要實現(xiàn)函數(shù)重載,可以使用3.4中增加的轉(zhuǎn)發(fā)機(jī)制即單分派泛型函數(shù)(single-dispatch generic function)來實現(xiàn)重載
11.2 單分派泛型函數(shù)
- 泛型函數(shù) generic function :由多個函數(shù)組成的函數(shù),可以根據(jù)不同的參數(shù)類型決定調(diào)用那個函數(shù)
- 單分派,single-dispatch:一種泛型函數(shù)分派形式,其中實現(xiàn)是根據(jù)單個參數(shù)的類型選擇的。
所以,單分派泛型函數(shù)就是根據(jù)函數(shù)的第一個參數(shù)類型決定使用哪個函數(shù)的泛型函數(shù)
將一個函數(shù)聲明為泛型函數(shù)可以使用修飾器@singledispatch,需要從functools模塊導(dǎo)入,singledispatch有兩個常用方法,register和dispatch
from functools import singledispatch@singledispatch def Foo(arg,*args):print(arg)這樣就實現(xiàn)了一個泛型函數(shù),他的分派發(fā)生在第一個參數(shù)類型上,如果想要基于此實現(xiàn)重載,需要使用他的register方法,
from functools import singledispatch@singledispatch def Foo(arg,*args):print(arg)# 使用了類型注釋 @Foo.register def _1(arg:int,*args):print(f'int - {arg}')# 沒有使用類型注釋,顯式傳遞給修飾器 @Foo.register(list) def _2(arg,*args):print(f'list - {arg}')if __name__ == '__main__':Foo(3) # int - 3Foo([i for i in range(10)]) # list - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]對于使用了類型注釋的變量,singledispatch會自動推斷第一個參數(shù)的類型,如上面int的那個,對于沒有使用類型注釋的變量,可以顯式傳遞類型給singledispatch,如下面list的那個
register屬性還可以以函數(shù)的形式調(diào)用,這可以用在lambdas表達(dá)式上,如
>>> def nothing(arg, verbose=False): ... print("Nothing.") ... >>> fun.register(type(None), nothing)如果沒有實現(xiàn)針對特定類型的注冊,那么就會使用被@singledispatch修飾的函數(shù)
Foo("string") # string要檢查泛型函數(shù)將為給定類型選擇哪個實現(xiàn),請使用dispatch()屬性
print(Foo.dispatch(int)) # <function _1 at 0x000001D7C2724B70> print(Foo.dispatch(list)) # <function _2 at 0x000001D7C2792E18> print(Foo.dispatch(str)) # <function Foo at 0x000001FB456FC268>要訪問所有已注冊的實現(xiàn),請使用只讀的registry屬性
11.3 總結(jié)
python默認(rèn)不支持重載,但可以使用單分派泛型函數(shù)實現(xiàn),聲明泛型函數(shù)需要使用修飾器@singledispatch,它有三個屬性,register用來注冊針對特定類型的“重載函數(shù)”,這里必須指明針對的是哪一個特定的類型,可以給第一個參數(shù)類型注釋,也可以給register傳入一個顯式類型,否則會拋出TypeError異常;dispatch屬性用來查看特定的類型將要選擇的函數(shù);registry用來訪問所有已注冊的實現(xiàn)。
參考鏈接:
functools.singledispatch
single dispatch
generic function
python中的重載
為什么 Python 不支持函數(shù)重載?其他函數(shù)大部分都支持的?
總結(jié)
以上是生活随笔為你收集整理的python 重载的实现(single-dispatch generic function)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 联想软件商店安装教程
- 下一篇: opencv python教程简书_Op