我试图用类型注释我的代码但是当涉及到集合时我有点困惑。我在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。
答案 0 :(得分:3)
注意注释和打字。 484中讨论的想法是全新的,并在typing
模块中实现。该模块仅在Python3.5中可用(对于Py2和Py3,typing
也可以使用最新的pip
。
https://docs.python.org/3/library/typing.html
你引用的那个注释来自484中开始的部分:
要打开对Python 3.5以及旧版本的静态类型检查的使用,需要统一的命名空间。为此,引入了标准库中的新模块,称为输入。
注释列出的是注释类型,而不是实际的对象类(内置或来自collections
)。不要混淆两者。
请注意,Dict
,List
,Set
和FrozenSet
全部大写,其中函数(和类型名称)为dict
,{{ 1}},list
,set
。换句话说,使用frozenset
或dict()
制作字典,而不是{}
。
注释是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.AbstractSet
和typing.MutableSet
是ABC的类型(抽象基类),而不是集合类型的具体实现:
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
的类型,它是不可变集的具体实现。答案 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)
晚会迟了两年,但无论如何......
您可以将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"
答案 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'
的默认参数