J'essaie d'annoter mon code avec des types mais je suis un peu confus en ce qui concerne les ensembles. J'ai lu certains points dans PEP 484:

Remarque: Dict, List, Set et FrozenSet sont principalement utiles pour annoter les valeurs de retour. Pour les arguments, préférez les types de collection abstraits définis ci-dessous, par ex. Cartographie, séquence ou ensemble abstrait.

Et

Set, renommé en AbstractSet. Ce changement de nom était nécessaire car Set dans le module de saisie signifie set () avec des génériques.

Mais cela n'aide pas.

Ma première question est: quelles sont les similitudes et les différences entre Set, FrozenSet, MutableSet et AbstractSet?

Ma deuxième question est: pourquoi si j'essaye

from collections import FrozenSet

Je reçois

ImportError: cannot import name 'FrozenSet'

?

J'utilise Python 3.4 et j'ai installé mypy-lang via pip.

10
marcotama 10 mars 2016 à 06:59

4 réponses

Meilleure réponse

Soyez prudent avec les annotations et la frappe. Les idées discutées en 484 sont toutes nouvelles et implémentées dans le module typing. Ce module n'est disponible qu'en Python3.5 (la dernière typing est également disponible auprès de pip pour Py2 et Py3).

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

Cette note que vous avez citée provient d'une section de 484 qui commence:

Pour ouvrir l'utilisation de la vérification de type statique à Python 3.5 ainsi qu'aux versions plus anciennes, un espace de noms uniforme est requis. À cet effet, un nouveau module dans la bibliothèque standard est introduit appelé la saisie.

Les choses que les listes de notes sont des types d'annotation, pas des classes d'objets réelles (intégrées ou de collections). Ne confondez pas les deux.

Notez que Dict, List, Set et FrozenSet sont tous en majuscule, alors que les fonctions (et les noms de type) sont dict, list , set, frozenset. En d'autres termes, pour créer un dictionnaire, vous utilisez dict() ou {}, pas Dict.

Les annotations sont nouvelles dans 3.0 (pas dans 2.n du tout). Dans un interpréteur ordinaire, ils ne font que remplir le dictionnaire __annotations__ de la fonction. Il n'y a rien dans l'interpréteur qui utilise ou nécessite des annotations.

http://mypy-lang.org/ se décrit comme un vérificateur de frappe expérimental. Vous devez consulter sa documentation pour voir à quel point il est compatible avec le 484, etc.

https://docs.python.org/3/library /collections.abc.html#module-collections.abc a quelques définitions abstraites, que je crois que typing utilise. Je ne les ai jamais utilisés. Ils sont principalement destinés aux personnes développant de nouvelles classes d'objets, et non aux utilisateurs «réguliers».

La balise typing pour cette question n'est probablement pas une bonne idée. Il n'a pas beaucoup de followers et est trop générique. Il ne fait pas référence à ce module Python.

Recherchez [python] 484 pour d'autres questions SO traitant de ce style d'annotations.

https://github.com/python/typing - le référentiel de développement typing.

Dans ce référentiel, il y a une définition FrozenSet dans le fichier python2/typing.py (le backport python2), mais pas dans src/typing.py. Je ne suis pas sûr de la signification de cela.

3
hpaulj 10 mars 2016 à 06:00

Deux ans de retard à la fête, mais enfin ...

Vous pouvez considérer AbstractSet et MutableSet comme une interface en Java ou une classe de base abstraite en Python. Les set() et frozenset() intégrés de Python sont une implémentation, mais quelqu'un pourrait créer une autre implémentation qui n'utilise pas du tout les intrinsèques.

FrozenSet et Set, d'autre part, représentent les types de béton construits dans les classes frozenset et set.

Par exemple, les types "interface" n'ont pas de méthodes union, contrairement aux types concrets. Donc:

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

Va taper check très bien, mais si vous changez le type de a en AbstractSet, mypy dit:

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

1
Martin C. Martin 4 mai 2018 à 04:58

Chacun d'eux est utilisé pour différentes choses.

Les ensembles sont très similaires au concept mathématique des ensembles: https://en.wikipedia.org/wiki / Set_ (mathématiques)

Un ensemble en Python est essentiellement une collection d'objets uniques. Vous pouvez en savoir plus sur les ensembles, ainsi que voir quelques exemples, ici: http: //www.python -course.eu/python3_sets_frozensets.php

Les ensembles en Python sont une collection d'objets uniques (tous immuables) mais un FrozenSet est immuable. Cela signifie que vous pouvez changer un ensemble, mais vous ne pouvez pas changer un FrozenSet: vous devez créer un nouveau FrozenSet.

En Python3, FrozenSet est un argument par défaut appelé 'frozenset'

-2
Ryan O'Donnell 10 mars 2016 à 04:07

Le type défini est modifiable - le contenu peut être modifié à l'aide de méthodes telles que add () et remove (). Puisqu'il est modifiable, il n'a pas de valeur de hachage et ne peut pas être utilisé comme clé de dictionnaire ou comme élément d'un autre ensemble. Le type frozenset est immuable et lavable - son contenu ne peut pas être modifié après sa création; cependant, il peut être utilisé comme clé de dictionnaire ou comme élément d'un autre ensemble.

À partir de: https://docs.python.org/3/library/stdtypes. html # frozenset

Vous n'avez pas besoin de l'inclure, il est intégré, il vous suffit de:

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

Testé en 3.4.2

0
Matt 3 févr. 2017 à 00:13