简体   繁体   English

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

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

I am trying to annotate my code with types but I am a little confused when it comes to sets.我正在尝试用类型注释我的代码,但在涉及集合时我有点困惑。 I read some points in PEP 484 :我在PEP 484 中阅读了一些要点:

Note: Dict , List , Set and FrozenSet are mainly useful for annotating return values.注意: Dict 、 List 、 Set 和 FrozenSet 主要用于注释返回值。 For arguments, prefer the abstract collection types defined below, eg Mapping , Sequence or AbstractSet .对于参数,更喜欢下面定义的抽象集合类型,例如 Mapping 、 Sequence 或 AbstractSet 。

and

Set, renamed to AbstractSet . Set,重命名为 AbstractSet 。 This name change was required because Set in the typing module means set() with generics.这个名称更改是必需的,因为类型模块中的 Set 意味着带有泛型的 set() 。

but this does not help.但这无济于事。

My first question is: what are the commonalities and differences between Set, FrozenSet, MutableSet and AbstractSet?我的第一个问题是:Set、FrozenSet、MutableSet 和 AbstractSet 的共性和区别是什么?

My second question is: why if I try我的第二个问题是:为什么如果我尝试

from collections import FrozenSet

I get我得到

ImportError: cannot import name 'FrozenSet'

? ?

I am using Python 3.4 and I have installed mypy-lang via pip.我正在使用 Python 3.4 并且我已经通过 pip 安装了 mypy-lang。

Be careful with annotations and typing.注意注释和打字。 The ideas discussed in 484 are brand new, and implemented in the typing module. 484 中讨论的想法是全新的,并在typing模块中实现。 That module is only available in Python3.5 (the latest typing is also available from pip for both Py2 and Py3).该模块仅在 Python3.5 中可用(Py2 和 Py3 的最新typing也可从pip获得)。

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

That note that you quoted is from a section in 484 that starts:您引用的那个注释来自 484 中的一个部分,该部分开始于:

To open the usage of static type checking to Python 3.5 as well as older versions, a uniform namespace is required.要在 Python 3.5 和旧版本中使用静态类型检查,需要一个统一的命名空间。 For this purpose, a new module in the standard library is introduced called typing .为此,标准库中引入了一个新模块,称为 Typing 。

The things that the note lists are annotation types, not actual object classes (builtin or from collections ).注释列表中的内容是注释类型,而不是实际的对象类(内置或来自collections )。 Don't confuse the two.不要混淆两者。

Note that Dict , List , Set and FrozenSet are all capitalized, where as the functions (and type names) are dict , list , set , frozenset .请注意, DictListSetFrozenSet都是大写的,其中函数(和类型名称)是dictlistsetfrozenset In other words to make a dictionary you use dict() or {} , not Dict .换句话说,要制作字典,您可以使用dict(){} ,而不是Dict

Annotations are new to 3.0 (not in 2.n at all).注释是 3.0 的新内容(根本不在 2.n 中)。 In a regular interpreter all they do is populate the function's __annotations__ dictionary.在常规解释器中,他们所做的只是填充函数的__annotations__字典。 There's nothing in the interpreter that uses or requires annotations.解释器中没有使用或需要注释的内容。

http://mypy-lang.org/ describes itself as an experiemental typing checker. http://mypy-lang.org/将自己描述为一个实验性的打字检查器。 You need to look at it's documentation to see how compatible it is with 484 etc.您需要查看它的文档以了解它与 484 等的兼容性。

https://docs.python.org/3/library/collections.abc.html#module-collections.abc has some abstract definitions, which I believe typing uses. https://docs.python.org/3/library/collections.abc.html#module-collections.abc有一些抽象定义,我相信typing用到这些定义。 I've never used these.我从来没有用过这些。 They are mainly for people developing new classes of objects, not 'regular' users.它们主要用于开发新类对象的人,而不是“常规”用户。

The typing tag for this question is probably not a good idea.这个问题的typing标签可能不是一个好主意。 It doesn't have many followers, and is too generic.它没有很多追随者,而且太笼统了。 It does not refer to this Python module.它不引用此 Python 模块。

Search for [python] 484 for other SO questions dealing with this style of annotations.搜索[python] 484以获取处理这种注释风格的其他 SO 问题。

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

In this repository, there is a FrozenSet definition in the python2/typing.py file (the python2 backport), but not in src/typing.py .在这个存储库中,在python2/typing.py文件(python2 backport)中有一个FrozenSet定义,但在src/typing.py I'm not sure of the significance of that.我不确定这有什么意义。

Two years late to the party, but anyway...晚会晚了两年,但无论如何......

You can think of AbstractSet and MutableSet as like an interface in Java or an abstract base class in Python.您可以将AbstractSetMutableSet视为 Java 中的接口或 Python 中的抽象基类。 Python's builtin set() and frozenset() are one implementation, but someone could create another implementation that doesn't use the builtins at all. Python 的内置set()frozenset()是一种实现,但有人可以创建另一种根本不使用内置函数的实现。

FrozenSet and Set , on the other hand, represent the types of the concrete built in classes frozenset and set .另一方面, FrozenSetSet代表了在类frozensetset内置的具体类型。

For example, the "interface" types don't have union methods, while the concrete types do.例如,“接口”类型没有union方法,而具体类型有。 So:所以:

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

will type check just fine, but if you change the type of a to AbstractSet , mypy says:将类型检查就好了,但如果你改变的类型, aAbstractSet ,mypy说:

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

The set type is mutable -- the contents can be changed using methods like add() and remove(). set 类型是可变的——可以使用 add() 和 remove() 等方法更改内容。 Since it is mutable, it has no hash value and cannot be used as either a dictionary key or as an element of another set.由于它是可变的,它没有哈希值,不能用作字典键或另一个集合的元素。 The frozenset type is immutable and hashable -- its contents cannot be altered after is created; frozenset 类型是不可变和可散列的——它的内容在创建后不能改变; however, it can be used as a dictionary key or as an element of another set.但是,它可以用作字典键或另一个集合的元素。

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

you don't need to include it, it's built in, you just do:你不需要包含它,它是内置的,你只需:

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

tested in 3.4.2在 3.4.2 中测试

These type names are indeed a little confusing.这些类型名称确实有点令人困惑。 There was a related discussion on mypy Gitter, and Guido provided a clarification .关于 mypy Gitter 有相关讨论,Guido 提供了澄清

typing.AbstractSet and typing.MutableSet are the types for ABCs (abstract base classes), not concrete implementations of the set type: typing.AbstractSettyping.MutableSet是 ABCs(抽象基类)的类型,而不是集合类型的具体实现:

  • typing.AbstractSet is the type for collections.abc.Set , which is an ABC (abstract base class) for an immutable set. typing.AbstractSetcollections.abc.Set的类型,它是不可变集合的 ABC(抽象基类)。
  • typing.MutableSet is the type for collections.abc.MutableSet , which is an ABC for a mutable set. typing.MutableSetcollections.abc.MutableSet的类型,它是可变集的 ABC。

typing.Set and typing.FrozenSet are the types for concrete set implementations, available in the stdlib: typing.Settyping.FrozenSet是具体集合实现的类型,可在 stdlib 中使用:

  • typing.Set is the type for stdlib set , which is a concrete implementation of a mutable set. typing.Set是 stdlib set的类型,它是可变集的具​​体实现。
  • typing.FrozenSet is the type for stdlib frozenset , which is a concrete implementation of an immutable set. typing.FrozenSet是 stdlib frozenset的类型,它是不可变集的具​​体实现。

Each of these are used for different things.这些中的每一个都用于不同的事情。

Sets are very similar to the mathematical concept of Sets: https://en.wikipedia.org/wiki/Set_(mathematics)集合与集合的数学概念非常相似: https : //en.wikipedia.org/wiki/Set_( mathematics )

A Set in Python is essentially a collection of unique objects. Python 中的 Set 本质上是唯一对象的集合。 You can read more about sets, as well as see some examples, here: http://www.python-course.eu/python3_sets_frozensets.php您可以在此处阅读有关集合的更多信息以及查看一些示例: http : //www.python-course.eu/python3_sets_frozensets.php

Sets in Python are a collection of unique objects (all immutable) but a FrozenSet is immutable. Python 中的集合是唯一对象的集合(都是不可变的),但 FrozenSet 是不可变的。 This means you can change a Set, but you cannot change a FrozenSet: you need to create a new FrozenSet.这意味着您可以更改 Set,但不能更改 FrozenSet:您需要创建一个新的 FrozenSet。

In Python3, FrozenSet is a default argument called 'frozenset'在 Python3 中,FrozenSet 是一个名为“frozenset”的默认参数

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

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