簡體   English   中英

這種與isinstance()混合使用的Python鴨子輸入方法是否有意義?

[英]Does this approach to Python duck-typing mixed with isinstance() make sense?

假設我們有以下課程:

class Duck(object):
    pass

class OldFashionedDuck(Organism, Duck):
    def look(self):
        self.display_biological_appearance()
    def walk(self):
        self.keep_balance_on_two_feet()
    def quack(self):
        self.make_noise_with_lungs("Quack!")

class ArtificialDuck(Robot, Duck):
    def look(self):
        self.display_imitation_biological_appearance()
    def walk(self):
        self.engage_leg_clockwork()
    def quack(self):
        self.play_sound("quack.au")

在此示例中,OldFashionedDuck和ArtificialDuck沒有通用實現,但是通過構造,它們都將為isinstance(...,Duck)返回True。

這並不完美,但是我認為這可能有助於尊重鴨子的輸入,並(通過空的mixin繼承)允許isinstance()。 從本質上講,它提供了滿足接口的協定,因此,它並不是基於完成所有工作的類來真正調用isinstance(),而是基於任何人都可以選擇加入的接口。

我看過基於“ isinstance()被認為是有害的”的文章,因為它破壞了鴨子的輸入。 但是,我至少作為程序員想知道,如果不一定要從哪里獲取對象的功能,那么我是否知道該對象是否實現了接口。

這種方法有用嗎?如果可以的話,可以改進嗎?

我看過基於“ isinstance()被認為是有害的”的文章,因為它破壞了鴨子的輸入。 但是,我至少作為程序員想知道,如果不一定要從哪里獲取對象的功能,那么我是否知道該對象是否實現了接口。

我認為您錯過了重點。

當我們談論“鴨子類型”時,我們真正的意思是不對接口進行形式化 因此,您要嘗試做的事情歸結為試圖回答以下問題:“如何在不使接口正式化的同時使接口正式化?”。

我們希望提供給我們的對象可以實現一個接口-我們描述了一個接口,而不是通過創建基類,而是通過編寫了一系列文檔並描述了行為(如果我們感覺特別煩躁,請設置某種接口)。測試套件)-因為我們說過這就是我們的期望(同樣在我們的文檔中)。 我們通過嘗試像使用該接口一樣使用該接口,並將產生的任何錯誤視為調用方的責任,來驗證該對象是否實現了該接口。 調用給我們錯誤對象的代碼是很頑皮的,這就是需要修復錯誤的地方。 (同樣,測試可以幫助我們追蹤這些情況。)

簡而言之,測試isinstance(this_fuzzball_that_was_handed_to_me, Duck)實際上並沒有幫助:

  • 它可以通過isinstance檢查,但是以違反我們期望的方式(或return NotImplemented )的方式實現這些方法。 只有真正的測試會在這里進行。

  • 它可以通過檢查,但實際上完全無法實現一種或多種方法。 畢竟,基本Duck不包含任何實現,Python沒有理由在派生類中檢查它們。

  • 也許更重要的是,即使它像鴨子一樣完美地可用,它也可能無法通過檢查。 可能是一些無關的對象直接具有quackwalklook功能,並作為屬性手動附加到該對象(與之相反,它們是其類的屬性,在查找時變成方法)。

好吧,你說,“不要那樣做”。 但是現在您正在為每個人做更多的工作; 如果客戶不總是選擇加入,那么使用鴨子的代碼進行檢查就沒有用,而且很危險。 同時,您獲得了什么?

這與EAFP原則有關:不要試圖通過觀察來確定某物是否是鴨子。 通過將其視為“鴨子”並處理“血腥的混亂”來找出它是否是鴨子。


但是,如果您不關心Duck的輸入哲學,並且絕對必須對某些事物施加某種嚴謹的外觀,那么您可能會對標准庫abc模塊感興趣。

即使我不想高估這個術語,但是:您的方法不是pythonic。 做鴨子打字,還是不做。

如果您想確保“接口”的實現能夠實現它應該執行的所有操作:請對其進行測試!

對於較小的項目,很容易記住您的需求。 您可以嘗試一下。

我同意對於大型項目,甚至團隊合作,最好確保您的類型具有所需的一切。 在這種情況下,您絕對應該使用單元測試來確保您的類型完整。 即使沒有鴨式打字,您也需要測試,因此可能不需要任何額外的測試。

吉多·范·羅蘇姆(Guido van Rossum)在這次演講中談到了一些有關鴨類打字的有趣想法。 它是如此鼓舞人心,絕對值得一看。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM