【问题标题】:How to use collections.abc from both Python 3.8+ and Python 2.7如何在 Python 3.8+ 和 Python 2.7 中使用 collections.abc
【发布时间】:2019-05-27 11:02:52
【问题描述】:

在 Python 3.3 中,collections(如MutableMappingMutableSequence)中的“抽象基类”被移至二级模块collections.abc。所以在 Python 3.3+ 中,真正的类型是 collections.abc.MutableMapping 等等。 Documentation 声明旧别名(例如 collections.MutableMapping)将在 Python 3.7(当前最新版本)之前可用,但在 3.8 中这些别名将被删除。

当您使用别名时,当前版本的 Python 3.7 甚至会产生警告:

./scripts/generateBoard.py:145: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  elif isinstance(value, (collections.MutableMapping, collections.MutableSequence)) == True:

在 python 2.7 中没有collections.abc

当 Python 脚本旨在与(几乎)任何 Python 版本一起使用时,如何以最方便的方式处理这种差异?我正在寻找一种解决方案,可以理想地在一个中心位置解决这个混乱,而不必在我需要这种类型的任何地方都使用try: ... except: ...

【问题讨论】:

  • 他们破坏了主要版本的向后兼容性。淘气。

标签: python python-3.x python-2.7


【解决方案1】:

把它放在脚本的顶部:

import collections

try:
    collectionsAbc = collections.abc
except AttributeError:
    collectionsAbc = collections

然后更改抽象基类型的所有前缀,例如将collections.abc.MutableMappingcollections.MutableMapping 更改为collectionsAbc.MutableMapping

或者,在一个地方的顶部的脚本中导入您需要的内容:

try:
    from collections.abc import Callable  # noqa
except ImportError:
    from collections import Callable  # noqa

【讨论】:

  • 第二种形式实际上更可取——因为当人们最终放弃 Python 2 时,只需删除 try/ 块。另一个配方添加了额外的中间名称,这些名称将在代码中保留为旧版。
  • @jsbueno 一方面,我完全同意您对第二种形式的敏锐观察,但是,我可以设想第一种形式的可读性优势,具体取决于您在文件顶部! FWIW,我使用的是第二种形式 ;-)
【解决方案2】:

看起来six 模块的新版本有collections_abc 别名,所以你可以使用:

from six.moves import collections_abc

【讨论】:

    【解决方案3】:

    解决这个问题的一种方法是简单地尝试从collections 获取abc,否则假设abc 的成员已经在collections 中。

    import collections                                         
    collections_abc = getattr(collections, 'abc', collections)
    

    【讨论】:

    • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助、质量更好,并且更有可能吸引投票。
    【解决方案4】:

    我遇到了这样的错误:

    C:\Users\gsc-30431\Anaconda3\lib\site-packages\unittest2\compatibility.py:148
      C:\Users\gsc-30431\Anaconda3\lib\site-packages\unittest2\compatibility.py:148: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is depr
    ecated since Python 3.3,and in 3.9 it will stop working
        class ChainMap(collections.MutableMapping):
    
    -- Docs: https://docs.pytest.org/en/latest/warnings.html
    

    所以我通过访问上面错误中显示的路径打开了文件Compatibility.py!并在那里搜索了使用此 Collections 包的代码并更改了上一行,即:

    class ChainMap(collections.MutableMapping):
    

    换行:

    class ChainMap(collections.abc.MutableMapping):
    

    截图:

    只需添加 .abc 就解决了我的问题,我不再收到警告!

    【讨论】:

    • 我刚刚尝试了同样的事情,它对我有用。话虽如此,我们刚刚做了什么?我正在努力确保这不会在未来造成任何问题。
    • 过去 8 个月我没有遇到任何问题。如果会产生任何问题,将来会寻找其他解决方案。
    猜你喜欢
    • 1970-01-01
    • 2020-02-03
    • 2020-09-06
    • 1970-01-01
    • 2021-03-21
    • 1970-01-01
    • 2017-11-04
    • 1970-01-01
    • 2018-11-06
    相关资源
    最近更新 更多