Python中的“容器”究竟是什么?(还有所有的Python容器类型是什么?)

75

Python文档经常提到“容器”(例如):

如果check_circular为False(默认为True),则会跳过对容器类型的循环引用检查,循环引用将导致OverflowError(或更糟)。

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

编辑

对于Python 2.7.3:

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

(isinstance(object, collections.Container)返回True)

  1. 具有定义__contains__方法的容器:

    • 所有内置序列类型:列表、bytearrays、字符串、Unicode字符串和元组。
    • 字典
    • 所有内置集合类型:集合和frozensets
  2. 没有定义__contains__方法的容器:

    • xrange对象

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

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

  • Int 对象
  • Float 对象
  • Long 对象
  • Boolean 对象
  • Module 对象
  • File 对象
  • Buffer 对象
  • None 对象

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

3个回答

103

容器是任何包含任意数量其他对象的对象。通常,容器提供访问所包含对象以及迭代它们的方式。

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

严格来说,collections.abc.Container抽象基类(collections.Container在 Python2 中)适用于任何支持通过__contains__魔术方法使用in运算符的类型;因此,如果您可以编写x in y,则y通常是一个容器,但不总是:容器和一般可迭代对象之间一个重要区别是:当迭代容器时,它们将返回它们持有引用的现有对象,而生成器和例如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__ 魔法方法。但是,在测试对象是否为容器时,您应该使用 isinstance(x, collections.abc.Container) 以获得清晰和向前兼容性,以防 Container 子类检查发生更改。


我认为这个答案不正确,因为它没有处理相反的情况。例如:>>> a = "hello" >>> isinstance(a, collections.abc.Container) True >>> 所以问题是:如何找出容器不是某些基本字符串?一种解决方法是确切地检查这一点。 - Christian Tismer

10
根据 http://docs.python.org/dev/library/collections.abc.html#module-collections.abc,容器的最一般定义就是实现了__contains__方法的对象。在Python中,“容器”或“序列”等概念并没有抽象地定义,而是通过它们的行为进行“鸭子类型”的判断。也就是说,容器就是你可以使用in运算符的东西。
Python的内置容器类型包括元组、列表、字典、集合、frozenset和str和unicode(在Python 3中是bytes和str),以及一些其他的构造体,这些构造体虽然技术上是类型,但在特定的上下文之外并不常用(例如缓冲区对象和xrange对象)。collections模块提供了一些额外的容器类型。

dir(xrange) 不返回 __contains__ 方法。dir(buffer) 也是如此。 - Bentley4
1
容器比这个范畴更广泛;它们是任何支持通过 in 进行测试的东西。请参阅 http://docs.python.org/reference/expressions.html#membership-test-details - Karl Knechtel

0

容器是所有包含其他对象(如listdict)的Python对象。 Container类型是一个ABC,它的行为像一个接口。 容器是实现__contains__方法的类。

这里是文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接