【问题标题】:Difference between from collections import Container and from collections.abc import Containerfrom collections import Container 和 from collections.abc import Container 的区别
【发布时间】:2019-09-16 20:37:34
【问题描述】:

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

  1. from collections import Container
  2. from collections.abc import Container

两个Containerhelp 函数返回相同的文档。

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__'})

这两个导入有什么区别?为什么我们允许两者都做?

更新

collections (Python 3.7.3) 导入Container 时收到弃用警告。

Python 3.8不能直接从collections导入。

>>> from collections import Container

ma​​in:1: DeprecationWarning: 从 'collections' 而不是从 'collections.abc' 使用或导入 ABC 已被弃用,并且在 3.8 它将停止工作

【问题讨论】:

    标签: python-3.x abc


    【解决方案1】:

    来自Python 3 documentation for the collections module

    在 3.3 版中更改:已移动 Collections Abstract Base Classescollections.abc 模块。为了向后兼容,它们继续可见 在这个模块中通过 Python 3.7。 随后,它们将被完全删除。

    这些“集合抽象基类”目前包括 AsyncGenerator, AsyncIterable, AsyncIterator, Awaitable, Bytestring, Callable, Collection, Container, Coroutine, Generator, Hashable, ItemsView, Iterable, Iterator, KeysView, Mapping, MappingView, MutableMapping, MutableSequence, MutableSet, Reversible, Sequence, Set, Sized, ValuesView.

    在 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 一起使用,无需额外的努力)。

    【讨论】:

      猜你喜欢
      • 2019-06-07
      • 2016-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 2020-07-23
      • 2019-07-07
      相关资源
      最近更新 更多