The python documentation frequently speaks of “containers”. E.g. :
If check_circular is False (default: True), then the circular
reference check for container types will be skipped and a circular
reference will result in an OverflowError (or worse).
But I can’t find any official definition of containers, neither a list of them.
Edit
For Python 2.7.3:
Checked builtin types which are containers:
(isinstance(object, collections.Container) returns True)
-
Containers which have a
__contains__method defined:- All builtin sequence types: Lists, bytearrays, strings, unicode strings and
tuples. - Dictionaries
- All builtin set types: sets and frozensets
- All builtin sequence types: Lists, bytearrays, strings, unicode strings and
-
Containers which do not have a
__contains__method defined:- xrange objects
Checked builtin types which are not containers:
(isinstance(object, collections.Container) returns False):
- Int objects
- Float objects
- Long objects
- Boolean objects
- Module objects
- File objects
- Buffer objects
- The None object
Tell me which other builtin types you have checked for isinstance(object, collections.Container) and I’ll add them to the list.
Containers are any object that holds an arbitrary number of other objects. Generally, containers provide a way to access the contained objects and to iterate over them.
Examples of containers include
tuple,list,set,dict; these are the built-in containers. More container types are available in thecollectionsmodule.Strictly speaking, the
collections.abc.Containerabstract base class (collections.Containerin Python2) holds for any type that supports theinoperator via the__contains__magic method; so if you can writex in ythenyis usually a container, but not always: an important point of difference between containers and general iterables is that when iterated over, containers will return existing objects that they hold a reference to, while generators and e.g.fileobjects will create a new object each time. This has implications for garbage collection and deep object traversal (e.g.deepcopyand serialisation).As an example,
iter(lambda: random.choice(range(6)), 0)supports theinoperator, but it is certainly not a container!The intent of the
Collections.abc.Containerabstract base class in only considering the__contains__magic method and not other ways of supporting theinoperator is that a true container should be able to test for containment in a single operation and without observably changing internal state. SinceCollections.abc.Containerdefines__contains__as an abstract method, you are guaranteed that ifisinstance(x, collections.abc.Container)thenxsupports theinoperator.In practice, then, all containers will have the
__contains__magic method. However, when testing whether an object is a container you should useisinstance(x, collections.abc.Container)for clarity and for forward compatibility should theContainersubclass check ever be changed.