亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

python?泛型函數(shù)--singledispatch的使用解讀

 更新時(shí)間:2022年09月28日 08:35:07   作者:晨曦之梟  
這篇文章主要介紹了python?泛型函數(shù)--singledispatch的使用解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

@functools.singledispatch

將一個(gè)函數(shù)轉(zhuǎn)變?yōu)閱我环峙傻姆盒秃瘮?shù)

用 @singledispatch裝飾一個(gè)函數(shù),將定義一個(gè)泛型函數(shù)。注意,我們創(chuàng)建的函數(shù)獲得分派的依據(jù)是第一個(gè)參數(shù)的類型:

from functools import singledispatch
@singledispatch
def fun(arg, verbose=False):
? ? if verbose:
? ? ? ? print("Let me just say,", end=" ")
? ? print(arg)

使用泛函數(shù)的register()屬性,重載泛函數(shù)的實(shí)現(xiàn)。泛函數(shù)的register()屬性是一個(gè)裝飾器。對(duì)于有類型注釋的函數(shù),這個(gè)裝飾器將自動(dòng)匹配第一個(gè)參為該類型的已注冊(cè)函數(shù)重載泛函數(shù):

@fun.register
def _(arg: int, verbose=False):
? ? if verbose:
? ? ? ? print("Strength in numbers, eh?", end=" ")
? ? print(arg)
@fun.register
def _(arg: list, verbose=False):
? ? if verbose:
? ? ? ? print("Enumerate this:")
? ? for i, elem in enumerate(arg):
? ? ? ? print(i, elem)

當(dāng)我們調(diào)用泛函數(shù)fun時(shí),泛函數(shù)根據(jù)第一個(gè)參數(shù)的類型來(lái)分派相應(yīng)的函數(shù)來(lái)重載實(shí)現(xiàn)。

第一個(gè)參數(shù)為int類型時(shí):

>>> fun(42, verbose=True)
Strength in numbers, eh? 42

第一個(gè)參數(shù)為list類型時(shí):

>>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True)
Enumerate this:
0 spam
1 spam
2 eggs
3 spam

如果用泛函數(shù)的register()屬性進(jìn)裝飾的函數(shù)的參數(shù)沒(méi)有類型注釋,那么我們可以在register()裝飾器中明確聲明合適的類型:

@fun.register(complex)
def _(arg, verbose=False):
? ? if verbose:
? ? ? ? print("Better than complicated.", end=" ")
? ? print(arg.real, arg.imag)
>>>fun(6+5j, verbose=True)
Better than complicated. 6.0 5.0

為了能注冊(cè)之前存在的函數(shù)和匿名函數(shù),register()屬性可以當(dāng)作功能函數(shù)使用。

def nothing(arg, verbose=False):
? ? print("Nothing.")
? ??
fun.register(type(None), nothing)
fun.register(int, ?lambda x, y, verbose=False: x+y) # 本人添加的,官網(wǎng)沒(méi)有這個(gè)例子

注:經(jīng)本人實(shí)驗(yàn),如果泛函數(shù)出兩個(gè)可分派的函數(shù),那么,泛涵數(shù)將選擇離調(diào)用最近的可分派的函數(shù),即,泛函數(shù)將分派在順序上最后定義的函數(shù)。

>>> fun(None)
Nothing.
>>>fun(1,2)
3

這個(gè)register()屬性將返回一個(gè)未被裝飾的函數(shù),這個(gè)函數(shù)將激活裝飾器的堆??臻g,同時(shí)為它創(chuàng)建一個(gè)獨(dú)的測(cè)試運(yùn)行單元。

>>>import decimal
>>> @fun.register(float)
... @fun.register(decimal.Decimal)
... def fun_num(arg, verbose=False):
... ? ? if verbose:
... ? ? ? ? print("Half of your number:", end=" ")
... ? ? print(arg / 2)
...
>>> fun_num is fun
False

如果泛函數(shù)給出的具體類型,沒(méi)有對(duì)應(yīng)的注冊(cè)函數(shù)的實(shí)現(xiàn),那么泛函數(shù)將去尋找更一般化的實(shí)現(xiàn)。用@singledispatch裝飾的原函數(shù)被注冊(cè)了基本類型–object類型,也就是說(shuō)如果找不到更好的實(shí)現(xiàn),那么將使用@singledispatch裝飾的原函數(shù):

注:此例由本人提供。

>>>fun(bool,verbose=True)
Let me just say, <class 'bool'>

使用只讀屬性registry,可查看我們都注冊(cè)了哪些類型的函數(shù)實(shí)現(xiàn)

>>> fun.registry.keys()
dict_keys([<class 'object'>, <class 'decimal.Decimal'>, <class 'float'>, <class 'int'>, <class 'list'>, <class 'complex'>, <class 'NoneType'>])
>>> fun.registry
{<class 'object'>: <function fun at 0x00000225F21AC268>, <class 'decimal.Decimal'>: <function fun_num at 0x00000225F2517378>, <class 'float'>: <function fun_num at 0x00000225F2517378>, <class 'int'>: <function <lambda> at 0x00000225F2596488>, <class 'list'>: <function _ at 0x00000225F25172F0>, <class 'complex'>: <function _ at 0x00000225F2596400>, <class 'NoneType'>: <function nothing at 0x00000225F258E400>}
>>> fun.registry[float]
<function fun_num at 0x00000225F2517378>
>>>fun.registry[object]
<function fun at 0x00000225F21AC268>

官方鏈接:https://docs.python.org/3/library/functools.html?highlight=functools wraps#functools.update_wrapper

singledispatch實(shí)現(xiàn)單分派泛函數(shù)和多分派泛函數(shù)

本次的主題是逐漸闖入無(wú)人區(qū)的泛型?。?!

說(shuō)到泛型,學(xué)過(guò)java的一定不陌生,泛型的本質(zhì)是參數(shù)化類型,也就是所操作的數(shù)據(jù)類型被指定為一個(gè)參數(shù)。但是,學(xué)過(guò)python的大家是否了解過(guò)這部分,或者是使用呢?

那么,python該如何實(shí)現(xiàn)泛型呢?

你別說(shuō),還真有一個(gè)庫(kù)可以實(shí)現(xiàn)!

我們首先導(dǎo)入singledispatch所在的庫(kù):

from functools import singledispatch

這個(gè)庫(kù)只能針對(duì)函數(shù)的第一個(gè)參數(shù)進(jìn)行泛型指定!

先指定一個(gè)主函數(shù)用singledispatch修飾一下,作為一個(gè)base, 之后在定義一些“子函數(shù)”用 @主函數(shù)名.register作為修飾器,并傳入一個(gè)參數(shù)作為“子函數(shù)”第一個(gè)參數(shù)的類型的判斷(只能傳入一個(gè)參數(shù))(這個(gè)參數(shù)就是“子函數(shù)”第一個(gè)參數(shù)的類型,也是主函數(shù)第一個(gè)參數(shù)的類型)。(注意:這里的子函數(shù)就是那個(gè)_,應(yīng)為這個(gè)子函數(shù)只在泛函數(shù)里面會(huì)使用到,所以我們干脆不指定他的名字QAQ, 函數(shù)的參數(shù)也和主函數(shù)一樣)

但是,這樣局限性也太大了,根本沒(méi)有什么實(shí)際用處,我們還要推廣到多分派泛函數(shù)!??!

多分派泛函數(shù)的實(shí)現(xiàn):(因?yàn)閜ython只能對(duì)第一個(gè)參數(shù)進(jìn)行判斷泛型,所以我們需要添加一些自己的代碼實(shí)現(xiàn)多分派反函數(shù))

 我們?cè)趩畏峙傻幕A(chǔ)上使用isinstance進(jìn)行了判斷,保證其他參數(shù)的類型的一致性。

以上的多分派泛函數(shù)也可以這樣寫(xiě):

 每一個(gè)子函數(shù)使用了兩個(gè)修飾器,但是這兩個(gè)修飾器都是針對(duì)第一個(gè)參數(shù)的。

!?。∧阋詾檫@樣就完結(jié)了???

python 3.5  推出了新特性——參數(shù)后面加一個(gè)冒號(hào)和函數(shù)后面加一個(gè)->的用法:

(冒號(hào)是指該參數(shù)應(yīng)該的參數(shù)類型,箭頭是指函數(shù)應(yīng)該的返回值)

他也是指定了參數(shù)的類型,但是呢,就算你傳入的類型和冒號(hào)后面的不一樣,也并不會(huì)報(bào)錯(cuò)(除非你有語(yǔ)法錯(cuò)誤),所以,這并不是泛型。

但是他和泛型也有些關(guān)系,這涉及到了register修飾器的第二個(gè)用法:

 省略了register的參數(shù),而使用’:‘符號(hào)進(jìn)行指定。

?。?!完結(jié)?。?!

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python使用sorted排序的方法小結(jié)

    Python使用sorted排序的方法小結(jié)

    這篇文章主要介紹了Python使用sorted排序的方法,結(jié)合三個(gè)實(shí)例分析了Python使用sorted方法進(jìn)行元素排序操作的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-07-07
  • Pycharm學(xué)習(xí)教程(7)虛擬機(jī)VM的配置教程

    Pycharm學(xué)習(xí)教程(7)虛擬機(jī)VM的配置教程

    這篇文章主要為大家詳細(xì)介紹了最全的Pycharm學(xué)習(xí)教程第七篇,Python快捷鍵相關(guān)設(shè)置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Python一行代碼實(shí)現(xiàn)ChatGPT接入微信機(jī)器人

    Python一行代碼實(shí)現(xiàn)ChatGPT接入微信機(jī)器人

    這篇文章主要為大家介紹了Python一行代碼實(shí)現(xiàn)ChatGPT接入微信機(jī)器人示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 對(duì)python的文件內(nèi)注釋 help注釋方法

    對(duì)python的文件內(nèi)注釋 help注釋方法

    今天小編就為大家分享一篇對(duì)python的文件內(nèi)注釋 help注釋方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • python 按不同維度求和,最值,均值的實(shí)例

    python 按不同維度求和,最值,均值的實(shí)例

    今天小編就為大家分享一篇python 按不同維度求和,最值,均值的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • 在Python中使用列表生成式的教程

    在Python中使用列表生成式的教程

    這篇文章主要介紹了在Python中使用列表生成式的教程,列表生成式是Python具有的重要特性,需要的朋友可以參考下
    2015-04-04
  • pycharm進(jìn)入科學(xué)模式以及退出方式

    pycharm進(jìn)入科學(xué)模式以及退出方式

    這篇文章主要介紹了pycharm進(jìn)入科學(xué)模式以及退出方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python顯示進(jìn)度條的方法

    Python顯示進(jìn)度條的方法

    這篇文章主要介紹了Python顯示進(jìn)度條的方法,以實(shí)例的形式進(jìn)行了詳細(xì)的分析,是一個(gè)非常實(shí)用的技巧,需要的朋友可以參考下
    2014-09-09
  • Python操作MySQL模擬銀行轉(zhuǎn)賬

    Python操作MySQL模擬銀行轉(zhuǎn)賬

    這篇文章主要為大家詳細(xì)介紹了Python操作MySQL模擬銀行轉(zhuǎn)賬,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • python 將md5轉(zhuǎn)為16字節(jié)的方法

    python 將md5轉(zhuǎn)為16字節(jié)的方法

    今天小編就為大家分享一篇python 將md5轉(zhuǎn)為16字節(jié)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05

最新評(píng)論