[英]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
)。 不要混淆两者。
请注意, Dict
、 List
、 Set
和FrozenSet
都是大写的,其中函数(和类型名称)是dict
、 list
、 set
、 frozenset
。 换句话说,要制作字典,您可以使用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
。 我不确定这有什么意义。
晚会晚了两年,但无论如何......
您可以将AbstractSet
和MutableSet
视为 Java 中的接口或 Python 中的抽象基类。 Python 的内置set()
和frozenset()
是一种实现,但有人可以创建另一种根本不使用内置函数的实现。
另一方面, FrozenSet
和Set
代表了在类frozenset
和set
内置的具体类型。
例如,“接口”类型没有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"
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.AbstractSet
和typing.MutableSet
是 ABCs(抽象基类)的类型,而不是集合类型的具体实现:
typing.AbstractSet
是collections.abc.Set
的类型,它是不可变集合的 ABC(抽象基类)。typing.MutableSet
是collections.abc.MutableSet
的类型,它是可变集的 ABC。 typing.Set
和typing.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.