繁体   English   中英

python 类型模块中的 Set、FrozenSet、MutableSet 和 AbstractSet 有什么区别?

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

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

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

Set,重命名为 AbstractSet 。 这个名称更改是必需的,因为类型模块中的 Set 意味着带有泛型的 set() 。

但这无济于事。

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

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

from collections import FrozenSet

我得到

ImportError: cannot import name 'FrozenSet'

?

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

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

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

您引用的那个注释来自 484 中的一个部分,该部分开始于:

要在 Python 3.5 和旧版本中使用静态类型检查,需要一个统一的命名空间。 为此,标准库中引入了一个新模块,称为 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用到这些定义。 我从来没有用过这些。 它们主要用于开发新类对象的人,而不是“常规”用户。

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

搜索[python] 484以获取处理这种注释风格的其他 SO 问题。

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

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

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

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

另一方面, FrozenSetSet代表了在类frozensetset内置的具体类型。

例如,“接口”类型没有union方法,而具体类型有。 所以:

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

将类型检查就好了,但如果你改变的类型, aAbstractSet ,mypy说:

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

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

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

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

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

在 3.4.2 中测试

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

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

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

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

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

这些中的每一个都用于不同的事情。

集合与集合的数学概念非常相似: 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”的默认参数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM