web-dev-qa-db-fra.com

Nom non défini dans l'annotation de type

Je travaille actuellement sur la création d'un module d'algèbre linéaire python pour le plaisir et pour la pratique du langage. J'ai récemment essayé d'ajouter des annotations de type au module, en tant que tel:

class Vector:
     # Various irrelevant implementation details
     def __add__(self, other: Vector) -> Vector:
        # More implementation details....

Cependant, lorsque j'essaie d'importer cela, il crache un NameError: Name 'Vector' is not defined. Je reconnais que cette question a déjà été répondue, sous une forme, ici , mais elle ne semble pas fournir une réponse complète à ma situation.

Ce que j'aimerais savoir:

  • J'ai défini la classe littéralement dans ce fichier. Pourquoi dit-on que le nom n'est pas défini?
  • Comment définir Vector de manière à ce qu'il puisse être utilisé pour les annotations (comme type)?
35
MutantOctopus

Vous avez une déclaration à terme; les fonctions (à lier en tant que méthodes) sont créées avant la classe, donc le nom Vector n'existe pas encore. Ce n'est que lorsque tout le corps de la classe a été exécuté, que Python crée l'objet class et y lie le nom Vector.

Utilisez simplement une chaîne avec le nom à la place:

class Vector:
     # Various irrelevant implementation details
     def __add__(self, other: 'Vector') -> 'Vector':
        # More implementation details....

Cela n'affecte pas la façon dont votre IDE voit la déclaration; les chaînes sont recherchées une fois que tout le module est chargé et sont résolues comme une expression valide Python dans étant donné que la classe Vector existe une fois que tout le module est chargé, la chaîne 'Vector' peut être correctement converti en objet classe.

Voir également spécification sur les références directes :

Lorsqu'un indice de type contient des noms qui n'ont pas encore été définis, cette définition peut être exprimée sous la forme d'un littéral de chaîne, à résoudre ultérieurement.

[...]

Le littéral de chaîne doit contenir une expression Python [...] valide) et il doit être évalué sans erreur une fois le module entièrement chargé.

43
Martijn Pieters

Si vous utilisez Python 3.7 et supérieur. Jetez un œil à Évaluation différée des annotations

Depuis Python 3.7, cela sera autorisé, ajoutez simplement:

from __future__ import annotations

Et notez également que

Il deviendra la valeur par défaut dans Python 4.0.

18
vishes_shell