python输入模块中Set,FrozenSet,MutableSet和AbstractSet有什么区别?

时间:2016-03-10 03:59:08

标签: python python-3.x type-hinting frozenset

我试图用类型注释我的代码但是当涉及到集合时我有点困惑。我在PEP 484中读到了一些要点:

  

注意:Dict,List,Set和FrozenSet主要用于注释返回值。对于参数,更喜欢下面定义的抽象集合类型,例如:映射,序列或AbstractSet。

  

设置,重命名为AbstractSet。此名称更改是必需的,因为键入模块中的Set表示使用泛型的set()。

但这没有帮助。

我的第一个问题是:Set,FrozenSet,MutableSet和AbstractSet之间的共性和区别是什么?

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

from collections import FrozenSet

我得到了

ImportError: cannot import name 'FrozenSet'

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

5 个答案:

答案 0 :(得分:3)

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

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

你引用的那个注释来自484中开始的部分:

  

要打开对Python 3.5以及旧版本的静态类型检查的使用,需要统一的命名空间。为此,引入了标准库中的新模块,称为输入。

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

请注意,DictListSetFrozenSet全部大写,其中函数(和类型名称)为dict,{{ 1}},listset。换句话说,使用frozensetdict()制作字典,而不是{}

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

http://mypy-lang.org/将自己描述为一种体验式打字检查器。您需要查看它的文档以了解它与484等的兼容性。

https://docs.python.org/3/library/collections.abc.html#module-collections.abc有一些抽象的定义,我相信__annotations__会使用它们。我从未使用过这些。它们主要用于开发新类别物体的人,而非常规物品。用户。

此问题的typing标记可能不是一个好主意。它没有很多粉丝,而且过于通用。它没有引用这个Python模块。

搜索typing以获取有关此注释风格的其他SO问题。

https://github.com/python/typing - [python] 484开发资源库。

在此存储库中,typing文件(python2 backport)中有FrozenSet定义,但python2/typing.py中没有。{1}}。我不确定其重要性。

答案 1 :(得分:1)

这些类型名称确实有点令人困惑。关于mypy Gitter进行了相关讨论,Guido提供了clarification

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

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

typing.Settyping.FrozenSet是具体集实现的类型,可在stdlib中找到:

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

答案 2 :(得分:0)

set类型是可变的 - 可以使用add()和remove()等方法更改内容。由于它是可变的,因此它没有哈希值,不能用作字典键或另一组的元素。 frozenset类型是不可变的和可清除的 - 其内容在创建后不能更改;但是,它可以用作字典键或另一组的元素。

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

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

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

在3.4.2中测试

答案 3 :(得分:0)

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

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

另一方面,

FrozenSetSet代表了类frozensetset中内置的具体类型。

例如,“接口”类型没有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"

答案 4 :(得分:-2)

每个都用于不同的事情。

集与集合的数学概念非常相似:https://en.wikipedia.org/wiki/Set_(mathematics)

Python中的Set本质上是唯一对象的集合。您可以在此处阅读有关集合的更多信息,以及一些示例:http://www.python-course.eu/python3_sets_frozensets.php

Python中的集合是唯一对象的集合(都是不可变的),但FrozenSet是不可变的。这意味着您可以更改Set,但不能更改FrozenSet:您需要创建一个新的FrozenSet。

在Python3中,FrozenSet是一个名为' frozenset'

的默认参数