gpt4 book ai didi

python - 这种将 Python 鸭子类型(duck typing)与 isinstance() 混合使用的方法是否有意义?

转载 作者:太空宇宙 更新时间:2023-11-04 07:43:21 24 4
gpt4 key购买 nike

假设我们有以下类:

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。

这并不完美,但我认为它可能有助于尊重鸭子类型(duck typing),并且(通过空混合继承)允许 isinstance()。从本质上讲,它提供了满足接口(interface)的契约,因此它并不是真正基于完成所有工作的类调用 isinstance(),而是基于任何人都可以选择加入的接口(interface)。

我看过基于“isinstance() 被认为是有害的”的文章,因为它破坏了 duck 类型。但是,至少作为一名程序员,我想知道,如果对象不一定从哪里获得函数,而是它是否实现了接口(interface)。

这种方法是否有用,如果有用,是否可以对其进行改进?

最佳答案

I've seen articles based on "isinstance() considered harmful," because it breaks duck typing. However, I at least as a programmer would like to know, if not necessarily where an object gets a function from, but whether it implements an interface.

我认为你没有捕获重点。

当我们谈论“鸭子类型(duck typing)”时,我们真正的意思是没有形式化我们的接口(interface)。因此,您尝试做的事情归结为尝试回答“我如何在仍未形式化我的界面的情况下形式化我的界面?”这个问题。

我们期望给我们一个对象来实现一个接口(interface)——我们描述的一个接口(interface),不是通过创建一个基类,而是通过编写一堆文档和描述行为(如果我们感觉特别活泼,设置建立某种测试套件)——因为我们说过这是我们所期望的(同样在我们的文档中)。我们通过尝试像使用它一样使用它来验证对象是否实现了接口(interface),并将任何由此产生的错误视为调用者的责任。调用给我们错误对象的代码是顽皮的,这就是需要修复错误的地方。 (同样,测试可以帮助我们追踪这些事情。)

简而言之,测试 isinstance(this_fuzzball_that_was_handed_to_me, Duck) 并没有真正的帮助:

  • 它可以通过 isinstance 检查,但以违反我们预期的方式实现方法(或者说,return NotImplemented)。只有真正的测试才会在这里进行。

  • 可以通过检查,但实际上完全没有实现其中的一个或多个方法;毕竟,基础 Duck 不包含任何实现,Python 没有理由在派生类中检查它们。

  • 也许更重要的是,它可能无法通过检查,即使它是一个完全可以用作鸭子类型(duck typing)的毛绒球。也许它是一些不相关的对象,它们具有 quackwalklook 函数,直接作为属性手动附加到它(而不是它们是它的类,在查找时成为方法)。

好吧,所以,“不要那样做”,你说。但是现在你正在为每个人做更多的工作;如果客户端不总是选择加入,那么使用鸭子类型(duck typing)的代码进行检查是无用且危险的。同时,您获得了什么?

这与 EAFP 原则有关:不要试图通过观察来判断某物是否是 Duck;通过将它视为鸭子类型(duck typing)来判断它是否是鸭子类型(duck typing),如果不是,则处理血淋淋的困惑。


但是,如果您不关心鸭子类型(duck typing)哲学,并且绝对必须强加一些表面上的严谨性,您可能会对标准库 abc 模块感兴趣。

关于python - 这种将 Python 鸭子类型(duck typing)与 isinstance() 混合使用的方法是否有意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14435122/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com