16

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

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

集,重命名为 AbstractSet 。之所以需要更改名称,是因为类型模块中的 Set 意味着带有泛型的 set()。

但这无济于事。

我的第一个问题是:Set、FrozenSet、MutableSet和AbstractSet有什么共同点和不同点?

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

from collections import FrozenSet

我明白了

ImportError: cannot import name 'FrozenSet'

?

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

4

4 回答 4

5

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

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

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

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

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

请注意DictList,SetFrozenSet都是大写的,其中函数(和类型名称)是dict, list, set, frozenset。换句话说,要使用dict()or {}, not来制作字典Dict

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

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

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

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

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

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

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

于 2016-03-10T04:50:21.843 回答
4

派对迟到了两年,但无论如何......

您可以将AbstractSetandMutableSet视为 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"

于 2018-05-04T04:58:19.677 回答
2

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

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

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

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

  • typing.Set是 stdlib 的类型set,它是可变集的具​​体实现。
  • typing.FrozenSet是 stdlib 的类型frozenset,它是不可变集的具​​体实现。
于 2020-09-06T00:17:39.053 回答
1

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

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

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

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

在 3.4.2 中测试

于 2016-03-10T04:09:56.030 回答