python中的“容器”究竟是什么? (什么是所有的Python容器types?)
python文档经常提到“容器”。 例如 :
如果check_circular是False(默认值:True),那么容器types的循环引用检查将被跳过,循环引用将导致OverflowError(或更糟糕)。
但我找不到任何官方的容器定义,既不是他们的名单。
编辑
对于Python 2.7.3:
检查了容器内置的types:
( isinstance(object, collections.Container)
返回True
)
-
容器中定义了
__contains__
方法:- 所有内置序列types:列表,字节码,string,Unicodestring和元组。
- 字典
- 所有内置的集合types:集合和frozensets
-
没有定义
__contains__
方法的容器:- xrange对象
检查不是容器的内置types:
( isinstance(object, collections.Container)
返回False
):
- Int对象
- 浮动对象
- 长物体
- 布尔对象
- 模块对象
- 文件对象
- 缓冲对象
- 无对象
告诉我你已经检查了哪些其他的内buildtypesisinstance(object, collections.Container)
,我将它们添加到列表中。
容器是包含任意数量的其他对象的任何对象。 一般来说,容器提供了访问包含的对象并遍历它们的方法。
容器的例子包括tuple
, list
, set
, dict
; 这些是内置的容器 。 collections
模块中提供了更多的容器types。
严格地说, collections.abc.Container
抽象基类(Python2中的collections.Container
)适用于任何通过__contains__
magic方法支持in
运算符的types; 所以如果你可以x in y
写x in y
那么y
通常是一个容器,但并不总是这样: 容器和一般迭代器之间的一个重要区别是,当迭代时,容器将返回他们持有的引用的现有对象,而生成器和例如file
对象每次都会创build一个新的对象。 这对垃圾收集和深层对象遍历(例如深度deepcopy
和序列化)有影响。
举个例子, iter(lambda: random.choice(range(6)), 0)
支持in
运算符,但肯定不是容器!
Collections.abc.Container
抽象基类只考虑__contains__
魔术方法而不支持in
运算符的其他方式的意图是真正的容器应该能够在单个操作中testing遏制并且不会明显改变内部状态。 由于Collections.abc.Container
将__contains__
定义为一个抽象方法,因此可以保证,如果isinstance(x, collections.abc.Container)
则x
支持in
运算符。
那么在实践中,所有的容器都会有__contains__
魔法。 但是,当testing一个对象是否是一个容器时isinstance(x, collections.abc.Container)
为了清晰起见,应该使用isinstance(x, collections.abc.Container)
,并且如果Container
子类检查被更改isinstance(x, collections.abc.Container)
应该使用前向兼容性。
根据http://docs.python.org/dev/library/collections.abc.html#module-collections.abc ,容器的最一般的定义是一个实现了__contains__
的对象。 一般来说,像“容器”或“序列”这样的Python概念没有被抽象地定义, 他们的行为是“鸭子式的”。 也就是说,一个容器是你可以使用in
运算符的东西。
Python内置的容器types是元组,列表,字典,集合,冷凝集和str和unicode(或者Python 3中的字节和string),以及其他一些技术types的构造,但是在特定的上下文之外不常用例如,缓冲区对象和xrange对象)。 collections
模块中提供了其他容器types。
容器都是包含像list
或dict
其他对象的python对象。 Container
types是一个ABC,它的行为就像一个接口。 Container是一个实现了__contains__
方法的类。
这是文档