问题标签 [duck-typing]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
1023 浏览

python - 鸭子打字:如何避免名称冲突?

我认为理解鸭子类型的想法,并希望在我的代码中更频繁地使用它。但是,我担心一个潜在的问题:名称冲突。

假设我想要一个对象做某事。我知道合适的方法,所以我简单地调用它,看看会发生什么。一般来说,有三种可能的结果:

  1. 找不到该方法并AttributeError引发异常。这表明该对象不是我认为的那样。没关系,因为使用鸭子打字我要么捕捉到这样的异常,要么我愿意让外部范围处理它(或让程序终止)。

  2. 方法找到了,它正是我想要的,一切都很好。

  3. 方法找到了,但不是我想要的方法;它是来自完全不相关的类的同名方法。执行将继续,直到稍后检测到不一致的状态,或者在最坏的情况下,程序会默默地产生不正确的输出。

现在,我可以看到优质名称如何降低结果#3 的机会。但是项目被合并,代码被重用,库被交换,并且很可能在某些时候两个方法具有相同的名称并且完全不相关(即,它们不打算在多态中相互替代)。

我正在考虑的一个解决方案是添加方法名称的注册表。每个注册表记录将包含:

  • 方法名称(唯一;即每个名称只有一条记录)
  • 它的概括描述(即,适用于它可能被调用的任何实例)
  • 它打算用于的一组类

如果将方法添加到新类,则需要将类添加到注册表(手动)。那时,程序员可能会注意到该方法是否与已经附加的含义不一致,并且如果需要,使用另一个名称。

每当调用方法时,程序会自动验证名称是否在注册表中,并且实例的类是记录中的类之一。如果不是,则会引发异常。

我知道这是一种非常繁重的方法,但在某些精度至关重要的情况下,我可以看到它可能很有用。是否尝试过(在 Python 或其他动态类型语言中)?有没有做类似事情的工具?还有其他值得考虑的方法吗?

注意:我不是指全局级别的名称冲突,避免命名空间污染是正确的方法。我指的是方法名称的冲突;这些不受名称空间的影响。

0 投票
1 回答
149 浏览

python - 在 Python 3.1 中使用 Duck 类型进行排序的最少方法

手册中说:

一般来说,如果您想要比较运算符的常规含义,就足够__lt__()__eq__()

但我看到了错误:

当我运行这个测试时:

我很惊讶什么时候IntVar()在右边,__int__()没有被调用。我究竟做错了什么?

添加__gt__()修复此问题,但意味着我不明白订购的最低要求是什么......

谢谢,安德鲁

0 投票
2 回答
731 浏览

ruby - 为什么 to_a 和 to_ary 在 Array 的子类中表现不同?

如果您有 Array 的子类 X,则doingX#to_a返回一个数组对象,而doingX#to_ary返回一个x 对象。

虽然我理解这to_a意味着“我可以变成一个数组”,而to_ary意味着“我的行为就像一个数组”,但我不明白为什么前者实现了类的改变而后者没有。

to_a此外,根据 Liskov 替换原则,返回 Array 的子类是否足够?

0 投票
3 回答
660 浏览

python - 鸭子类型和类方法(或者,如何使用类和实例中的方法?)

我有一些代码,我想交替传递实例或类。我在该代码中要做的就是调用一个我希望类和实例都具有的方法(go()下面示例中的方法)。

不幸的是,我不能创建一个与常规方法同名的类方法......见下面的例子。我最初预计第二次调用会产生一个a而不是一个b.

关于如何实现这一目标的任何建议?

0 投票
2 回答
980 浏览

c#-4.0 - 使用 ImpromptuInterface 时如何解决此枚举转换问题?

给定以下代码:

以下测试失败:

有没有办法正确解决这个问题?

0 投票
3 回答
921 浏览

programming-languages - 函数式编程和强类型之间有什么联系吗?

所有“纯”函数式语言都是强类型的。这些之间有什么联系吗?

0 投票
3 回答
695 浏览

c++ - 用 C++ 输入鸭子的模板

有没有办法要求模板类型具有属性?

例如:

T那么,我将如何要求operator()(U a, U b)定义返回特定类型?这可能吗?(我知道它在 d 中,但我不确定 c++)。

附言。如果鸭子在这里输入错误,请告诉我,我相信它是正确的,但我不确定。

0 投票
3 回答
1587 浏览

ruby - Ruby 的'is_a?' 为内置类型返回 false,发生了什么?

我只学习了 Ruby 的深层部分几个月,所以如果这是一个有点愚蠢的问题,我深表歉意。我正在尝试递归迭代一个可能包含嵌套数组的数组,因此我需要检查当前元素的类型。我有以下代码作为一个小测试:

当我运行它时,我得到以下输出:

我希望最后两个返回 True,因为我有一个包含 Range 和两个嵌套数组的数组。

更奇怪的是,如果我写以下内容:

它应该返回 True。

这里发生了什么事?

红宝石版本: MRI 1.9.3-p194

注意:我最终意识到这是由于我使用模块命名我的代码以避免代码冲突的方式,就像这样,但也以一种顽皮的方式验证对象身份:

这样做会隔离您的代码,但会导致从您的命名空间下开始解析所有类查找。这意味着在上面的示例中,my_array.class实际上会解析为MyProg::Array而不是全局 Array 类。

如果你像这样命名空间并且你仍然想使用这个方法,你可以通过在类之前使用双冒号全局标识符来强制 Ruby 从全局命名空间开始查找来解决它:

然而,鉴于 Ruby 的 Duck Typing 能力(以及以后更好的代码维护),您应该按照下面彼得的建议测试对象的行为。因此,我将他的答案标记为正确,以便为学习者提供一些极好的帮助!

0 投票
4 回答
228 浏览

python - 如何正确合并鸭子类型以返回原始类型?

我真的希望这不是重复的。我试图搜索我的问题,但似乎找不到。

所以我有一个相当简单的函数将英尺转换为米:

这很好用并且接受整数、浮点数、数组和列表。但是,如果我放入一个列表(而不是一个 numpy 数组),我希望返回一个列表。所以我写了这个:

(或者return list(numpy.array(val) * 0.3084),如果我想在numpy这里使用,我可以使用最后一行,我不知道这是否真的很重要。)

这是在此处合并鸭子类型的最佳方法,以便我可以避免使用该type功能吗?最初我尝试过AttributeError,但没有奏效。TypeError尽管如此,即使它似乎有效,我仍然感到厌倦。

使用它会亵渎神明if type(val) is list吗?

0 投票
2 回答
358 浏览

python - python将2个相似的对象与鸭子类型进行比较

也许我的设计完全不合时宜,但如果我有 2 个可比较的派生类对象,但 D1 类基本上总是 > D2 类。(例如将 Ivy Bridge 与 286 进行比较)。如果不使用 isinstance(D2),我将如何实现 D1 类的比较以反映这一点?

我看到了这个: 比较两个对象如果在 Python 中进行鸭子类型,你应该测试 isinstance 吗?

我可以添加一个“类型”属性,然后比较类型,但我还不如使用 isinstance。最简单的方法是使用 isinstance... 有更好的建议吗?