【问题标题】:Is there an official or common knowledge standard minimal interface for a "list-like" object?“类似列表”的对象是否有官方或常识标准最小接口?
【发布时间】:2015-05-04 16:34:16
【问题描述】:

我不断看到像thisthis 这样的函数和文档(仅举几例)类似列表的对象进行操作或引用。 p>

我很清楚实际列表到底是什么 (dir(list)),并且可以从列表中推断出在大多数对“列表-像对象”,但是我看到它被引用的次数给我留下了以下问题:

“类列表”对象是否有官方或常识标准的最小接口? 是像实现__getitem__ 这样简单,还是同意像__len__ 这样的附加内容和__setitem__ 也需要吗?

这可能看起来像语义,但我不禁认为,如果不存在标准的最小接口要求,“list-likeness”的各种想法可能会导致一些问题/不正确处理。也许这只是 Python 的鸭子类型的一个小缺点?

【问题讨论】:

  • 欢迎来到鸭打字的精彩世界。
  • @aruisdante 这些是一些非常糟糕的仅链接答案,没有解决 OP 的问题。
  • @cpburnz 虽然它们绝对只是链接,而不是在解释链接方面的最高质量,但我不确定您如何不提供标准 python 协议的完整列表( list-like 固执地是,因此建议重复),没有链接到它们,特别是因为链接是到核心 python 文档。 SO 肯定不适合这样的存储库。话虽如此,Antii 的回答肯定涵盖了具体情况,这就是为什么我赞成它。
  • @aruisdante 参考文献很棒,但仅仅链接到它们对于 stackoverflow 的答案来说是不够的。应提供信息摘要。此外,data model 文档非常密集。在不了解事物的工作原理的情况下,还不清楚哪种方法与哪种协议相匹配。

标签: python list


【解决方案1】:

“类列表对象”的技术术语是序列。至少它支持排序(即具有相同元素但顺序不同的两个对象不相等)、索引(foo[bar] 使得bar 是小于序列长度的整数)和包含检查(@ 987654323@),并且具有给定的长度。它应该支持迭代,但如果不支持,那么 Python 将使用索引来模拟它。

【讨论】:

  • 我认为“可变序列”会更准确。例如,元组是一个序列,但它不像列表那样支持项目分配 (__setitem__)。如果一个函数被记录为采用类似列表的对象,那么它很可能打算改变该对象。
  • @iCodez:我们同意不同意。我个人认为修改可变参数是一种病态行为,因为无法保证(当然,除了文档之外)参数将是可变的。
  • python 数据模型非常明确地指出列表是可变序列。任何指定类似列表的 API 几乎肯定会期望可变,否则它会(或至少应该)使用不同的术语。用作输入和输出的参数的优劣实际上并不是 Python 数据模型范围的一部分。此外,API 可能会指定它返回类似列表,在这种情况下,关于修改输入的要点是没有实际意义的。
  • @aruisdante 如果您对这些声明有引用,您应该将它们作为答案发布。
  • 完全不清楚这是否意味着合同。特别是,像“一些”序列(支持扩展切片)这样的术语表明它是描述性的。现在,list 确实 支持扩展切片,但“类似列表”需要它而不是支持它的其他方法(或者,就此而言,isinstance(..., list ))。我也很想知道 append 不是可变序列的一部分:“可变序列应该提供方法 append()、count()、index()、extend()、insert()、pop()、remove( )、reverse() 和 sort(),类似于 Python 标准列表对象。”
【解决方案2】:

几乎任何时候你在 Python 文档中看到“-like object”,作者都是故意含糊其辞。作者认为枚举所有需要的接口太麻烦了,只是说它的一些接口是必需的。实现了所有接口的对象可以保证工作,但在大多数情况下,它可以与实现少得多的对象一起工作。

使用“类似列表的对象”,除了检查源代码之外,您能做的最好的事情就是推断它是否需要任何可变接口。如果它只需要对列表进行只读访问,则可以确定不需要实现任何可变序列操作。

如果它说“类似列表的对象或迭代器”,您可以提供一些实现更简单的迭代器接口的东西。

【讨论】:

    【解决方案3】:

    请参阅collections.abc 模块。在那里列出的抽象基类中,Python 中的list 实现了IterableContainerSizedSequenceMutableSequence。现在,其中的IterableSequenceMutableSequence 可以随便称为类列表

    但是,我会理解术语 list-like 意味着它是一个 MutableSequence - 至少具有 __getitem____setitem____delitem____len__ 方法, 也期望它具有文档中提到的 mixin 方法,例如append

    如果不需要__setitem____delitem__,则应将其称为序列-假设如果某物接受序列,则它不需要是可变的,因此strbytes , tuple 等也在那里工作。


    您的两个链接突出了该术语的模糊性:

    plotly API 要求 list-like 对象将由内部 PlotlyJSONEncoder 序列化为 JSON 数组,该内部 PlotlyJSONEncoder 将大部分编码委托给 Python JSONEncoder。但是,后者仅将 tuplelist(和子类)编码为 JSON 数组;因此这里的 list-like 表示listtuple 或其子类。不是任何一个子类的自定义序列对象将导致TypeError: [...] is not JSON serializable

    您链接到的unzip recipe 需要一个行为类似于Sequence 的对象(不需要可变性),因此tuplestr 或任何实现Sequence 的自定义对象都可以。


    TL;DR list-like 是一个模糊的术语。最好使用术语可迭代、序列和可变序列,因为它们已在 collections.abc 中定义。

    【讨论】:

    • 这清楚了很多。因此,尽管没有“标准”最小定义(回答我的主要问题),但您说它可能应该(或可能被普遍接受)引用 MutableSequence?
    • 或者更好的是调用Iterable、Sequence、MutableSequence或list,而不是像list-like这样模糊的东西
    • 干杯。我想整个术语都很糟糕。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-02
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    相关资源
    最近更新 更多