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__
方法的容器:
没有定义__contains__
方法的容器:
检查的不是容器的内置类型:
(isinstance(object, collections.Container)
返回False
):
告诉我您检查了哪些其他内置类型 isinstance(object, collections.Container)
,我会将它们添加到列表中。
【问题讨论】:
【参考方案1】:容器是包含任意数量的其他对象的任何对象。通常,容器提供了一种访问所包含对象并对其进行迭代的方法。
容器示例包括tuple
、list
、set
、dict
;这些是内置容器。 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对象,例如list
或dict
。 Container
类型是一个 ABC,它的行为类似于一个接口。 Container 是一个实现__contains__
方法的类。
这里是doc
【讨论】:
以上是关于python中的“容器”到底是啥? (以及所有的 python 容器类型是啥?)的主要内容,如果未能解决你的问题,请参考以下文章