如何在Python 3.8+和Python 2.7中使用collections.abc

Fre*_*pin 12 python python-2.7 python-3.x

在Python 3.3中,collections(如MutableMappingMutableSequence)中的“抽象基类” 被移至了第二级模块collections.abc。因此,在Python 3.3+中,实际类型为collections.abc.MutableMapping依此类推。文档指出,旧别名(例如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:
Run Code Online (Sandbox Code Playgroud)

在python 2.7中没有collections.abc

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

Fre*_*pin 20

将其放在脚本的顶部:

import collections

try:
    collectionsAbc = collections.abc
except AttributeError:
    collectionsAbc = collections
Run Code Online (Sandbox Code Playgroud)

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

另外,也可以在顶部的脚本中单个导入所需的内容:

try:
    from collections.abc import Callable  # noqa
except ImportError:
    from collections import Callable  # noqa
Run Code Online (Sandbox Code Playgroud)

  • 第二种形式实际上是可取的-当最终放弃Python 2时,只需删除try / block即可。其他配方添加了其他中间名称,该中间名称将保留为代码中的旧名称。 (5认同)

Ale*_*rub 5

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

from six.moves import collections_abc
Run Code Online (Sandbox Code Playgroud)


jvd*_*lon 5

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

import collections                                         
collections_abc = getattr(collections, 'abc', collections)
Run Code Online (Sandbox Code Playgroud)

  • 请不要仅发布代码作为答案,还要提供解释您的代码的作用以及它如何解决问题的问题。带解释的答案通常更有帮助,质量也更好,并且更有可能吸引点赞。 (3认同)