python typing 模块中的 Set、FrozenSet、MutableSet 和 AbstractSet 之间有什么区别?

What are the differences between Set, FrozenSet, MutableSet and AbstractSet in python typing module?

我正在尝试用类型注释我的代码,但在涉及集合时我有点困惑。我在 PEP 484:

中阅读了一些要点

Note: Dict , List , Set and FrozenSet are mainly useful for annotating return values. For arguments, prefer the abstract collection types defined below, e.g. Mapping , Sequence or AbstractSet .

Set, renamed to AbstractSet . This name change was required because Set in the typing module means set() with generics.

但这并没有帮助。

我的第一个问题是:Set、FrozenSet、MutableSet和AbstractSet之间的共性和差异是什么?

我的第二个问题是:为什么我尝试

from collections import FrozenSet

我明白了

ImportError: cannot import name 'FrozenSet'

?

我正在使用 Python 3.4 并且我已经通过 pip 安装了 mypy-lang。

集合类型是可变的 -- 可以使用 add() 和 remove() 等方法更改内容。因为它是可变的,所以它没有散列值,不能用作字典键或另一个集合的元素。 frozenset 类型是不可变且可散列的——其内容在创建后不能更改;但是,它可以用作字典键或另一个集合的元素。

来自:https://docs.python.org/3/library/stdtypes.html#frozenset

你不需要包含它,它是内置的,你只需要做:

cities = frozenset(["Frankfurt", "Basel","Freiburg"])

在 3.4.2 中测试

注意注释和打字。 484 中讨论的想法是全新的,并在 typing 模块中实现。该模块仅在 Python3.5 中可用(对于 Py2 和 Py3,最新的 typing 也可从 pip 获得)。

https://docs.python.org/3/library/typing.html

您引用的注释来自 484 中的一个部分,开头为:

To open the usage of static type checking to Python 3.5 as well as older versions, a uniform namespace is required. For this purpose, a new module in the standard library is introduced called typing .

笔记列出的东西是注释类型,而不是实际对象 类(内置或来自 collections)。不要混淆两者。

请注意 DictListSetFrozenSet 都是大写的,其中函数(和类型名称)是 dictlistsetfrozenset。换句话说,要制作字典,您可以使用 dict(){},而不是 Dict.

注解是 3.0 的新功能(根本不在 2.n 中)。在常规解释器中,它们所做的只是填充函数的 __annotations__ 字典。解释器中没有任何内容使用或需要注释。

http://mypy-lang.org/ 自称是一个实验性的打字检查器。您需要查看它的文档以了解它与 484 等的兼容性如何。

https://docs.python.org/3/library/collections.abc.html#module-collections.abc 有一些抽象定义,我相信 typing 使用。我从来没有用过这些。它们主要用于开发新 类 对象的人,而不是 'regular' 用户。

这个问题的 typing 标签可能不是一个好主意。它的追随者不多,而且过于笼统。它不引用此 Python 模块。

搜索 [python] 484 以获取处理此类注释的其他 SO 问题。

https://github.com/python/typing - typing 开发库。

在此存储库中,python2/typing.py 文件(python2 向后移植)中有一个 FrozenSet 定义,但 src/typing.py 中没有。我不确定这有什么意义。

聚会晚了两年,但无论如何...

您可以将 AbstractSetMutableSet 视为 Java 中的接口或 Python 中的抽象基础 class。 Python 的内置 set()frozenset() 是一个实现,但有人可以创建另一个根本不使用内置的实现。

FrozenSetSet则表示class中frozensetset中混凝土的类型。

例如,"interface" 类型没有 union 方法,而具体类型有。所以:

def merge(a: Set[str], b: Iterable[str]) -> Set[str]:
    return a.union(b)

会进行类型检查,但如果将 a 的类型更改为 AbstractSet,mypy 会说:

typetest.py:7: error: "AbstractSet[str]" has no attribute "union"

这些类型名称确实有点混乱。 mypy Gitter上有相关讨论,Guido提供了一个clarification.

typing.AbstractSettyping.MutableSet 是 ABC 的类型(抽象基础 classes),不是集合类型的具体实现:

  • typing.AbstractSetcollections.abc.Set 的类型,它是不可变集合的 ABC(抽象基础 class)。
  • typing.MutableSetcollections.abc.MutableSet 的类型,它是可变集的 ABC。

typing.Settyping.FrozenSet 是具体集合实现的类型,在标准库中可用:

  • typing.Set 是 stdlib set 的类型,它是可变集的具​​体实现。
  • typing.FrozenSet是stdlib的类型frozenset,是不可变集合的具体实现。