L'une des fonctionnalités les plus discutées de Python 3.5 est les indications de type .
Un exemple d' indices de type est mentionné dans cet article et celui-ci tout en mentionnant également d'utiliser les indices de type de manière responsable. Quelqu'un peut-il expliquer davantage à leur sujet et quand ils doivent être utilisés et quand non?
python
python-3.x
python-3.5
type-hinting
Vaulstein
la source
la source
Réponses:
Je suggère de lire le PEP 483 et PEP 484 et de regarder cette présentation de Guido sur Type Hinting.
En un mot : l' indication de type est littéralement ce que signifient les mots, vous indiquez le type des objets que vous utilisez .
En raison de la dynamique nature de Python, déduire ou vérifier le type d'un objet utilisé est particulièrement difficile. Ce fait rend difficile pour les développeurs de comprendre ce qui se passe exactement dans le code qu'ils n'ont pas écrit et, surtout, pour les outils de vérification de type trouvés dans de nombreux IDE [PyCharm, PyDev viennent à l'esprit] qui sont limités du fait que ils n'ont aucun indicateur du type des objets. En conséquence, ils ont recours à essayer de déduire le type avec (comme mentionné dans la présentation) un taux de réussite d'environ 50%.
Pour prendre deux diapositives importantes de la présentation Type Hinting:
Pourquoi saisir des indices?
TypeErrors
..
et en faisant apparaître des méthodes / attributs qui ne sont pas définis pour un objet.Pourquoi utiliser des vérificateurs de type statiques?
En guise de note de clôture pour cette petite introduction : Ceci est une option fonctionnalité et, d'après ce que je comprends, elle a été introduite afin de profiter de certains des avantages de la frappe statique.
Vous n'avez généralement pas besoin de vous en soucier et vous n'avez certainement pas besoin de l'utiliser (en particulier dans les cas où vous utilisez Python comme langage de script auxiliaire). Il devrait être utile lors du développement de grands projets car il offre la robustesse, le contrôle et les capacités de débogage supplémentaires nécessaires .
Tapez Hinting avec mypy :
Afin de rendre cette réponse plus complète, je pense qu'une petite démonstration conviendrait. J'utiliserai
mypy
la bibliothèque qui a inspiré les conseils de type tels qu'ils sont présentés dans le PEP. Ceci est principalement écrit pour quiconque se heurte à cette question et se demande par où commencer.Avant de le faire, permettez-moi de répéter ce qui suit: PEP 484 n'applique rien; il s'agit simplement de définir une direction pour les annotations de fonction et de proposer des directives sur la manière dont la vérification de type peut / doit être effectuée. Vous pouvez annoter vos fonctions et suggérer autant de choses que vous le souhaitez; vos scripts s'exécuteront malgré la présence d'annotations car Python lui-même ne les utilise pas.
Quoi qu'il en soit, comme indiqué dans le PEP, les types d'indices doivent généralement prendre trois formes:
# type: type
Commentaires spéciaux qui complètent les deux premiers formulaires. (Voir: Que sont les annotations variables dans Python 3.6? Pour une mise à jour Python 3.6 pour les# type: type
commentaires)De plus, vous souhaiterez utiliser des indications de type conjointement avec le nouveau
typing
module introduit dansPy3.5
. Dans ce document, de nombreux ABC (classes de base abstraites) (supplémentaires) sont définis ainsi que des fonctions d'assistance et des décorateurs à utiliser dans la vérification statique. La plupartABCs
encollections.abc
sont inclus , mais dans uneGeneric
forme afin de permettre l' abonnement (en définissant un__getitem__()
méthode).Pour toute personne intéressée par une explication plus approfondie de ceux-ci, le
mypy documentation
est très bien écrit et possède de nombreux exemples de code démontrant / décrivant la fonctionnalité de leur vérificateur; cela vaut vraiment la peine d'être lu.Annotations de fonction et commentaires spéciaux:
Tout d'abord, il est intéressant d'observer certains des comportements que nous pouvons obtenir lors de l'utilisation de commentaires spéciaux. Des
# type: type
commentaires spéciaux peuvent être ajoutés lors des affectations de variables pour indiquer le type d'un objet s'il ne peut pas être directement déduit. Les affectations simples sont généralement faciles à déduire, mais d'autres, comme les listes (en ce qui concerne leur contenu), ne le peuvent pas.Remarque: Si nous voulons utiliser un dérivé de
Containers
et devons spécifier le contenu de ce conteneur, nous devons utiliser les types génériques dutyping
module. Ceux-ci prennent en charge l'indexation.Si nous ajoutons ces commandes à un fichier et les exécutons avec notre interprète, tout fonctionne très bien et
print(a)
imprime simplement le contenu de la listea
. Les# type
commentaires ont été rejetés, traités comme des commentaires simples qui n'ont aucune signification sémantique supplémentaire .En exécutant cela avec
mypy
, d'autre part, nous obtenons la réponse suivante:Indiquant qu'une liste d'
str
objets ne peut pas contenir unint
qui, statiquement parlant, est sain. Cela peut être résolu soit en respectant le typea
et en ajoutant uniquement desstr
objets, soit en changeant le type du contenu dea
pour indiquer que toute valeur est acceptable (effectuée de manière intuitive avecList[Any]
afterAny
a été importée depuistyping
).Les annotations de fonction sont ajoutées sous la forme
param_name : type
après chaque paramètre de votre signature de fonction et un type de retour est spécifié à l'aide de la-> type
notation avant le signe deux-points de la fonction de fin; toutes les annotations sont stockées dans l'__annotations__
attribut de cette fonction dans un dictionnaire pratique. En utilisant un exemple trivial (qui ne nécessite pas de types supplémentaires dutyping
module):L'
annotated.__annotations__
attribut a maintenant les valeurs suivantes:Si nous sommes un noobie complet, ou si nous connaissons les
Py2.7
concepts et que nous ne sommes donc pas conscients de ce qui seTypeError
cache dans la comparaison deannotated
, nous pouvons effectuer une autre vérification statique, détecter l'erreur et nous éviter des ennuis:Entre autres choses, l'appel de la fonction avec des arguments invalides sera également intercepté:
Ceux-ci peuvent être étendus à pratiquement tous les cas d'utilisation et les erreurs détectées s'étendent plus loin que les appels et les opérations de base. Les types que vous pouvez vérifier sont vraiment flexibles et je viens de donner un petit aperçu de son potentiel. Un coup d'oeil dans le
typing
module, les PEP ou lesmypy
docs vous donnera une idée plus complète des capacités offertes.Fichiers de raccord:
Les fichiers de raccord peuvent être utilisés dans deux cas différents qui ne s'excluent pas mutuellement:
Les fichiers de raccord (avec une extension de
.pyi
) sont une interface annotée du module que vous créez / souhaitez utiliser. Ils contiennent les signatures des fonctions que vous souhaitez vérifier avec le corps des fonctions supprimées. Pour avoir une idée de cela, étant donné un ensemble de trois fonctions aléatoires dans un module nommérandfunc.py
:Nous pouvons créer un fichier stub
randfunc.pyi
, dans lequel nous pouvons placer des restrictions si nous le souhaitons. L'inconvénient est que quelqu'un qui regarde la source sans le talon n'obtiendra pas vraiment cette aide d'annotation lorsqu'il essaiera de comprendre ce qui est censé être passé où.Quoi qu'il en soit, la structure d'un fichier de raccord est assez simpliste: ajoutez toutes les définitions de fonction avec des corps vides (
pass
remplis) et fournissez les annotations en fonction de vos besoins. Ici, supposons que nous ne voulons travailler qu'avec desint
types pour nos conteneurs.La
combine
fonction donne une indication de la raison pour laquelle vous voudrez peut-être utiliser des annotations dans un fichier différent, elles encombrent parfois le code et réduisent la lisibilité (gros no-no pour Python). Vous pouvez bien sûr utiliser des alias de type, mais cela crée parfois plus de confusion que cela n'aide (alors utilisez-les judicieusement).Cela devrait vous familiariser avec les concepts de base des conseils de type en Python. Même si le vérificateur de type utilisé a été,
mypy
vous devriez progressivement commencer à en voir davantage, certains en interne dans les IDE ( PyCharm ) et d'autres en tant que modules python standard. J'essaierai d'ajouter des vérificateurs supplémentaires / packages connexes dans la liste suivante quand et si je les trouve (ou si suggéré).Dames que je connais :
Forfaits / projets connexes :
Le
typeshed
projet est en fait l'un des meilleurs endroits où vous pouvez regarder pour voir comment les indications de type peuvent être utilisées dans votre propre projet. Prenons comme exemple les__init__
dunders de laCounter
classe dans le.pyi
fichier correspondant :Où
_T = TypeVar('_T')
est utilisé pour définir les classes génériques . Pour laCounter
classe, nous pouvons voir qu'elle ne peut prendre aucun argument dans son initialiseur, en obtenir un simpleMapping
de n'importe quel type vers unint
ou prendre unIterable
de n'importe quel type.Remarque : Une chose que j'ai oublié de mentionner est que le
typing
module a été introduit à titre provisoire . Depuis PEP 411 :Prenez donc les choses ici avec une pincée de sel; Je doute qu'il soit supprimé ou modifié de manière significative, mais on ne peut jamais le savoir.
** Un autre sujet tout à fait, mais valide dans le cadre des indices de type
PEP 526
:: La syntaxe des annotations de variable est un effort pour remplacer les# type
commentaires en introduisant une nouvelle syntaxe qui permet aux utilisateurs d'annoter le type de variables dans desvarname: type
instructions simples .Voir Que sont les annotations variables dans Python 3.6? , comme mentionné précédemment, pour une petite introduction sur ces derniers.
la source
Ajoutant à la réponse élaborée de Jim:
Vérifiez le
typing
module - ce module prend en charge les indications de type comme spécifié par PEP 484 .Par exemple, la fonction ci-dessous prend et renvoie des valeurs de type
str
et est annotée comme suit:Le
typing
module prend également en charge:la source
Le PyCharm 5 récemment sorti prend en charge les indications de type. Dans leur article de blog à ce sujet (voir les conseils de type Python 3.5 dans PyCharm 5 ), ils offrent une excellente explication de ce que sont et ne sont pas les conseils de type, ainsi que plusieurs exemples et illustrations pour les utiliser dans votre code.
De plus, il est pris en charge dans Python 2.7, comme expliqué dans ce commentaire :
la source
L'indice de type est un ajout récent à un langage dynamique où les gens ont juré pendant des décennies des conventions de dénomination aussi simples que le hongrois (étiquette d'objet avec la première lettre b = booléen, c = caractère, d = dictionnaire, i = entier, l = liste, n = numérique , s = string, t = tuple) n'étaient pas nécessaires, trop encombrants, mais ont maintenant décidé que, oh attendez ... il est beaucoup trop difficile d'utiliser le langage (type ()) pour reconnaître les objets, et nos IDE fantaisistes besoin d'aide pour tout ce qui est compliqué, et que les valeurs d'objet attribuées dynamiquement les rendent complètement inutiles de toute façon, alors qu'une simple convention de dénomination aurait pu tout résoudre, pour n'importe quel développeur, d'un simple coup d'œil.
la source
Les indices de type sont pour la maintenabilité et ne sont pas interprétés par Python. Dans le code ci-dessous, la ligne
def add(self, ic:int)
ne génère pas d'erreur jusqu'à lareturn...
ligne suivante :la source