来自集合导入容器和来自collections.abc导入容器的区别

时间:2019-04-27 16:44:09

标签: python-3.x abc

我们可以通过两种方式导入Container

  1. from collections import Container
  2. from collections.abc import Container
两个help

Container函数返回相同的文档。

help(collections.Container)

Help on class Container in module collections.abc:

class Container(builtins.object)
 |  Methods defined here:
 |  
 |  __contains__(self, x)
 |  
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |  
 |  __subclasshook__(C) from abc.ABCMeta
 |      Abstract classes can override this to customize issubclass().
 |      
 |      This is invoked early on by abc.ABCMeta.__subclasscheck__().
 |      It should return True, False or NotImplemented.  If it returns
 |      NotImplemented, the normal algorithm is used.  Otherwise, it
 |      overrides the normal algorithm (and the outcome is cached).
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __abstractmethods__ = frozenset({'__contains__'})

help(collections.abc.Container)

Help on class Container in module collections.abc:

class Container(builtins.object)
 |  Methods defined here:
 |  
 |  __contains__(self, x)
 |  
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |  
 |  __subclasshook__(C) from abc.ABCMeta
 |      Abstract classes can override this to customize issubclass().
 |      
 |      This is invoked early on by abc.ABCMeta.__subclasscheck__().
 |      It should return True, False or NotImplemented.  If it returns
 |      NotImplemented, the normal algorithm is used.  Otherwise, it
 |      overrides the normal algorithm (and the outcome is cached).
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __abstractmethods__ = frozenset({'__contains__'})

这两种进口之间有什么区别?为什么我们允许两者都做?

更新

Containercollections)导入Python 3.7.3时出现弃用警告。

不能从Python 3.8直接从collections导入。

>>> from collections import Container
  

主要:1:弃用警告:不建议使用“集合”而不是“ collections.abc”中的ABC或从中导入ABC,在   3.8它会停止工作

1 个答案:

答案 0 :(得分:1)

来自Python 3 documentation for the collections module

  

在版本3.3中已更改:   Collections Abstract Base Classes   到collections.abc   模块。为了向后兼容,它们仍然可见   通过Python 3.7在此模块中。   随后,它们将被完全删除。

这些“集合抽象基类”当前包括 AsyncGeneratorAsyncIterableAsyncIteratorAwaitableBytestringCallableCollectionContainerCoroutineGeneratorHashableItemsViewIterableIteratorKeysViewMappingMappingViewMutableMappingMutableSequenceMutableSetReversibleSequenceSetSizedValuesView

在Python 3.8中,从collections导入它们将停止工作。 在Python 3.3至3.7中,可以从collections或 来自collections.abc(给出完全相同的类)。 在Python 3.7中,从collections导入它们会打印一个 弃用警告,因为Python 3.8即将发布。

在Python 2中,它们只能从“集合”中导入, 不是来自“ collections.abc”。

一种简单的处理方法是try / except块:

try:  # works in Python >= 3.3
    from collections.abc import Sequence
except ImportError:  # Python 2, Python <= 3.2
    from collections import Sequence

另一种常用的解决方法是有条件地 从collectionscollections.abc导入 在使用的Python版本上。

例如,使用一个PY2布尔值并执行:

if PY2:
    from collections import Sequence
else:
    from collections.abc import Sequence

通常使用six获得此布尔值:

from six import PY2

或使用sys.version_info

import sys
PY2 = int(sys.version_info[0]) == 2

如果我们预计Python 4可能会像Python 3.3+一样工作 在这方面,特殊外壳的Python 2似乎更适合未来 而不是特殊外壳的Python 3,可以通过以下方式完成:

if PY3:
    from collections.abc import Sequence
else:
    from collections import Sequence

其中的PY3布尔值可以使用six获得:

from six import PY3

或使用sys.version_info

import sys
PY3 = int(sys.version_info[0]) == 3

尽管上面的try / except方法似乎更强大 (例如,它可以轻松地与Python 3.2一起使用)。