【问题标题】:How to document a duck type?如何记录鸭子类型?
【发布时间】:2011-12-24 23:16:58
【问题描述】:

我的文档很臃肿,因为每当我遇到复杂的鸭子类型时,我都需要用某种方式说“这种鸭子类型”,但却陷入了“你的函数需要这个输入的这个”的无休止循环,但不记录它”,然后记录它。这会导致文档臃肿、重复,例如:

def Foo(arg):
    """
    Args:
      arg: An object that supports X functionality, and Y functionality,
        and can be passed to Z other functionality.
    """
    # Insert code here.

def Bar(arg):
    """
    Args:
      arg: An object that supports X functionality, and Y functionality,
        and can be passed to Z other functionality.
    """
    # Insert code here.

以此类推,以此类推,用于BazQux 和其他函数。我需要一些更短的写法“arg is a (type of object)”。

对于某些鸭子类型,它就像“类 dict 对象”一样简单:我们知道我们对 dict 的期望,因此我们知道要传递什么。 dict,或者可以模仿它的东西。

我觉得 C++ 对模板类型也有同样的问题。 Haskell 会拥有它,但可以使用类型类的定义来记录它。 (注意:Haskell 类!= Java/C++/Python/etc 中的类。)(注意:我并没有真正使用 Haskell 编程,如果这是一个糟糕的例子,请原谅我。)

我应该走传统的 OO 路线,只写一个基类,然后在文档中说“像这个基类这样的东西”吗?代码不会强制从基类派生(因为不需要从基类派生对象),并且基类基本上没有添加任何值,除了记录接口的属性。

另一方面,我正在编写 Python 编程,并且我尝试使用一种语言的习语进行编程。 (否则通常会造成伤害。)基类有利于继承功能,但是当您的基类完全抽象时,它似乎不会在鸭子类型语言中增加价值。


编辑:回答:我知道什么是鸭式打字(从帖子中应该很明显)。我在哪里记录它是一个问题,尤其是。当不存在可附加文档的类时。

【问题讨论】:

  • 我喜欢“表现得像”这个词,并保持文档化需求的一般性,除非有特定的理由需要公开更多细节。例如,如果只需要一个索引器和计数,我仍然会说“就像一个列表”。对于其他类型,它是相同的:“x 像动物一样行动”,其中“狗是动物”的想法可能在其他地方被记录/确保。
  • @pst:是的,但是什么是动物,我们对动物有什么期望,我们在哪里记录它?
  • class Animalclass Dog 在某处,有自己的文档 :) Python 非常植根于类实例模型。

标签: python documentation duck-typing


【解决方案1】:

duck typing 背后的想法是,您记录下您期待的是一只鸭子,而其他对象则可以假装自己是一只鸭子。

文档中没有任何 API 指定它接受 StringIO 对象;但是,我们可以在大多数需要“类文件对象”的地方使用它们。

此外,在大多数情况下,标准库会尽量避免命名鸭子类型所需的特定方法。这使得实施可以改变。例如,random.sample API 可以根据迭代或序列进行定义。

如果您想比这更具体,可以使用abstract base classescollections module(例如 Iterable、Hashable 和 Sized)或 numbers module(Rational、Integral 等)中已经包含了几个。模仿那些编写自己的模型并不难。然后,文档仅提及需要哪些 ABC(例如,xSized IterableyIntegral)。

【讨论】:

  • 最后一段:我的鸭子类型是新类型,所以要编写抽象基类。
【解决方案2】:

duck typing 的重点在于“类型”的概念变成了一种抽象的直观概念,而不是语言形式上的一部分。与类型检查是语言一部分的语言相比,这使得输入更加流畅和灵活。

使用鸭式打字时需要的不是程序知道您正在使用什么“类型”,而是其他程序员知道。因此,如果您有一整套对特定“类型”对象进行操作的类/函数/等,并且该类型无法用几句话来描述,只需在 cmets 或文档字符串中添加一个部分(甚至一个外部 .txt 文件)描述您的类型并命名它。然后你就可以在任何地方引用那个名字了。

【讨论】:

    【解决方案3】:

    更严格的类型化语言,如 Java,具有“接口”的概念:实现该接口的任何类都应该提供的方法集合。

    我想你可以借用这个概念而不必携带严格类型的包袱:只需定义和记录一个抽象类 Foo,然后说你的方法需要“FooFoo-like目的”。如果您不想这样做,您甚至不必让任何其他类实际继承自 Foo;阅读文档的人仍然会知道去哪里了解Foo-like 对象的预期内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-11
      • 2011-03-23
      相关资源
      最近更新 更多