Comment puis-je indiquer à PyCharm le type attendu d'un paramètre?


173

En ce qui concerne les constructeurs, les affectations et les appels de méthode, l'EDI PyCharm est assez bon pour analyser mon code source et déterminer le type de chaque variable. Je l'aime quand c'est bon, car cela me donne une bonne complétion de code et des informations sur les paramètres, et cela me donne des avertissements si j'essaye d'accéder à un attribut qui n'existe pas.

Mais quand il s'agit de paramètres, il ne sait rien. Les listes déroulantes de complétion de code ne peuvent rien afficher, car elles ne savent pas de quel type sera le paramètre. L'analyse de code ne peut pas rechercher d'avertissements.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

peasant = Person("Dennis", 37)
# PyCharm knows that the "peasant" variable is of type Person
peasant.dig_filth()   # shows warning -- Person doesn't have a dig_filth method

class King:
    def repress(self, peasant):
        # PyCharm has no idea what type the "peasant" parameter should be
        peasant.knock_over()   # no warning even though knock_over doesn't exist

King().repress(peasant)
# Even if I call the method once with a Person instance, PyCharm doesn't
# consider that to mean that the "peasant" parameter should always be a Person

Cela a un certain sens. D'autres sites d'appel peuvent transmettre n'importe quoi pour ce paramètre. Mais si ma méthode s'attend à ce qu'un paramètre soit de type, disons, pygame.Surfacej'aimerais pouvoir l'indiquer à PyCharm d'une manière ou d'une autre, afin qu'il puisse me montrer tous Surfaceles attributs de dans sa liste déroulante de complétion de code, et mettre en évidence les avertissements si J'appelle la mauvaise méthode, et ainsi de suite.

Y a-t-il un moyen de donner un indice à PyCharm et de dire "psst, ce paramètre est censé être de type X"? (Ou peut-être, dans l'esprit des langages dynamiques, "ce paramètre est censé charmer comme un X"? Je serais d'accord avec ça.)


EDIT: La réponse de CrazyCoder, ci-dessous, fait l'affaire. Pour tous les nouveaux venus comme moi qui veulent un résumé rapide, le voici:

class King:
    def repress(self, peasant):
        """
        Exploit the workers by hanging on to outdated imperialist dogma which
        perpetuates the economic and social differences in our society.

        @type peasant: Person
        @param peasant: Person to repress.
        """
        peasant.knock_over()   # Shows a warning. And there was much rejoicing.

La partie pertinente est la @type peasant: Personligne de la docstring.

Si vous allez également dans Fichier> Paramètres> Outils intégrés Python et que vous définissez "Format Docstring" sur "Epytext", alors Affichage> Recherche rapide de documentation de PyCharm imprimera assez bien les informations des paramètres au lieu de simplement imprimer toutes les @ -lines telles quelles.


7
Il est à noter que les commentaires reStructuredText utilisent les mêmes balises écrites différemment: @param xx: yyydevient :param xx: yyy. Voir jetbrains.com/pycharm/webhelp/…
Wernight

1
Pourquoi pouvons-nous nous en tirer de ne pas spécifier de nom de classe pleinement qualifié?
Jesvin Jose

Réponses:


85

Oui, vous pouvez utiliser un format de documentation spécial pour les méthodes et leurs paramètres afin que PyCharm puisse connaître le type. La version récente de PyCharm prend en charge les formats doc les plus courants .

Par exemple, PyCharm extrait les types des commentaires de style @param .

Voir aussi les conventions reStructuredText et docstring (PEP 257).

Une autre option est les annotations Python 3.

Veuillez vous référer à la section de documentation PyCharm pour plus de détails et d'échantillons.


2
Je pense que PyCharm a un peu changé son format doc (voir jetbrains.com/help/pycharm/… ), mais merci! Le manque d'intellisense sur les paramètres me rendait fou.
talons du

46

Si vous utilisez Python 3.0 ou version ultérieure, vous pouvez également utiliser des annotations sur les fonctions et les paramètres. PyCharm les interprétera comme le type que les arguments ou les valeurs de retour devraient avoir:

class King:
    def repress(self, peasant: Person) -> bool:
        peasant.knock_over() # Shows a warning. And there was much rejoicing.

        return peasant.badly_hurt() # Lets say, its not known from here that this method will always return a bool

Parfois, cela est utile pour les méthodes non publiques, qui n'ont pas besoin de docstring. Comme avantage supplémentaire, ces annotations sont accessibles par code:

>>> King.repress.__annotations__
{'peasant': <class '__main__.Person'>, 'return': <class 'bool'>}

Mise à jour : Depuis PEP 484 , qui a été accepté pour Python 3.5, c'est également la convention officielle de spécifier les types d'argument et de retour à l'aide d'annotations.


4
... et il existe plusieurs packages qui utilisent de telles anntoations pour effectuer une vérification de type à l'exécution. Ceci est à la fois plus pratique à utiliser et plus facile à lire que de faire de même par assertions et peut être utilisé de manière sélective tout de même. typecheck-decoratorest l'un de ces packages et contient un résumé des autres dans sa documentation. (Flexible aussi: vous pouvez même faire une saisie de canard avec vérification de type!)
Lutz Prechelt

5

PyCharm extrait les types d'une chaîne @type pydoc. Voir la documentation PyCharm ici et ici , et la documentation Epydoc . C'est dans la section «héritage» de PyCharm, il manque peut-être certaines fonctionnalités.

class King:
    def repress(self, peasant):
        """
        Exploit the workers by hanging on to outdated imperialist dogma which
        perpetuates the economic and social differences in our society.

        @type peasant: Person
        @param peasant: Person to repress.
        """
        peasant.knock_over()   # Shows a warning. And there was much rejoicing.

La partie pertinente est la @type peasant: Personligne de la docstring.

Mon intention n'est pas de voler des points à CrazyCoder ou au questionneur original, donnez-leur certainement leurs points. Je pensais juste que la réponse simple devrait être dans une case «réponse».


2

J'utilise PyCharm Professional 2016.1 en écrivant du code py2.6-2.7, et j'ai trouvé qu'en utilisant reStructuredText, je peux exprimer les types d'une manière plus succincte:

class Replicant(object):
    pass


class Hunter(object):
    def retire(self, replicant):
        """ Retire the rogue or non-functional replicant.
        :param Replicant replicant: the replicant to retire.
        """
        replicant.knock_over()  # Shows a warning.

Voir: https://www.jetbrains.com/help/pycharm/2016.1/type-hinting-in-pycharm.html#legacy


1

Vous pouvez également affirmer pour un type et Pycharm l'inférera:

def my_function(an_int):
    assert isinstance(an_int, int)
    # Pycharm now knows that an_int is of type int
    pass
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.