python中的“容器”到底是啥? (以及所有的 python 容器类型是啥?)

Posted

技术标签:

【中文标题】python中的“容器”到底是啥? (以及所有的 python 容器类型是啥?)【英文标题】:What exactly are "containers" in python? (And what are all the python container types?)python中的“容器”到底是什么? (以及所有的 python 容器类型是什么?) 【发布时间】:2012-07-19 12:40:25 【问题描述】:

python 文档经常提到“容器”。 E.g.:

如果 check_circular 为 False(默认:True),则循环 容器类型的引用检查将被跳过并循环 引用将导致溢出错误(或更糟)。

但我找不到任何容器的官方定义,也找不到它们的列表。

编辑

对于 Python 2.7.3:

检查的内置类型是容器:

isinstance(object, collections.Container) 返回True

    定义了__contains__ 方法的容器:

    所有内置序列类型:列表、字节数组、字符串、Unicode 字符串和 元组。 字典 所有内置集合类型:集合和frozensets

    没有定义__contains__ 方法的容器:

    xrange 对象

检查的不是容器的内置类型:

isinstance(object, collections.Container) 返回False):

Int 对象 浮动对象 长对象 布尔对象 模块对象 文件对象 缓冲区对象 无对象

告诉我您检查了哪些其他内置类型 isinstance(object, collections.Container),我会将它们添加到列表中。

【问题讨论】:

【参考方案1】:

容器是包含任意数量的其他对象的任何对象。通常,容器提供了一种访问所包含对象并对其进行迭代的方法。

容器示例包括tuplelistsetdict;这些是内置容器collections 模块中提供了更多容器类型。

严格来说,collections.abc.Container 抽象基类(Python2 中的collections.Container)适用于通过__contains__ 魔术方法支持in 运算符的任何类型;所以如果你可以写x in y,那么y通常是一个容器,但并不总是:containers和一般iterables之间的一个重要区别点em> 是当迭代时,容器将返回它们持有引用的现有对象,而生成器和例如file 对象每次都会创建一个新对象。这对垃圾收集和深度对象遍历有影响(例如deepcopy 和序列化)。

例如,iter(lambda: random.choice(range(6)), 0) 支持 in 运算符,但它肯定不是容器!

Collections.abc.Container 抽象基类仅考虑 __contains__ 魔术方法而不考虑支持 in 运算符的其他方式的意图是,真正的容器应该能够在单个操作中测试容器,并且没有明显改变内部状态。由于Collections.abc.Container__contains__ 定义为抽象方法,因此可以保证如果isinstance(x, collections.abc.Container)x 支持in 运算符。

实际上,所有容器都将具有__contains__ 魔术方法。但是,在测试对象是否为容器时,如果 Container 子类检查发生更改,您应该使用 isinstance(x, collections.abc.Container) 以保持清晰和向前兼容。

【讨论】:

您是否还包括所有可迭代的容器? (y 在for x in y @Bentley4 大多数可迭代对象是容器,但不是全部,例如生成器和file 对象。如果一个可迭代对象为它产生的所有东西创建一个新对象而不是一个现有对象,那么它就不是一个容器。 如果是这样,那么声称每个用作in y 的y 对象都是一个容器是错误的。 (例如,您所说的文件对象)。所以“Karl Knechtel”的评论是错误的? @Bentley4 如果y 是一个容器,那么x in y 将起作用。但是x in y 也适用于非容器(生成器、文件)。 isinstance(y, collections.abc.Container) 是正确的测试方式。 @Bentley4 collections.abc.Container 是 Python3,collections.Container 是 Python2。【参考方案2】:

根据http://docs.python.org/dev/library/collections.abc.html#module-collections.abc,容器最一般的定义就是实现__contains__的对象。一般来说,像“容器”或“序列”这样的 Python 概念不是抽象定义的;他们的行为是“鸭式”的。也就是说,容器是可以使用in 运算符的东西。

Python 内置容器类型是 tuple、list、dict、set、frozenset 和 str 和 unicode(或 Python 3 中的 bytes 和 str),以及其他一些技术上属于类型但不常用的构造特定的上下文(例如,缓冲区对象和 xrange 对象)。 collections 模块中提供了其他容器类型。

【讨论】:

dir(xrange) 不返回 __contains__ 方法。 dir(buffer) 也没有 容器比这更广泛一些;它们是任何支持通过in 进行测试的东西。见docs.python.org/reference/… 那么至少所有可迭代对象都是容器?是否有任何不可迭代但具有__contains__ 方法的内置类型?【参考方案3】:

容器都是包含其他对象的python对象,例如listdictContainer 类型是一个 ABC,它的行为类似于一个接口。 Container 是一个实现__contains__ 方法的类。

这里是doc

【讨论】:

以上是关于python中的“容器”到底是啥? (以及所有的 python 容器类型是啥?)的主要内容,如果未能解决你的问题,请参考以下文章

STL 中的双端队列到底是啥?

UIPageViewController 中的脊椎到底是啥?

GLib 和 GObject 到底是啥?

证书中的“主题”是啥意思? [关闭]

Docker是啥?

ReactJS 中的动态路由到底是啥