Come posso dire a PyCharm che tipo dovrebbe essere un parametro?


173

Quando si tratta di costruttori, assegnazioni e chiamate di metodi, l'IDE di PyCharm è abbastanza bravo nell'analizzare il mio codice sorgente e nel capire quale tipo dovrebbe essere ogni variabile. Mi piace quando è giusto, perché mi dà un buon completamento del codice e informazioni sui parametri e mi dà avvisi se provo ad accedere ad un attributo che non esiste.

Ma quando si tratta di parametri, non sa nulla. I menu a discesa di completamento del codice non possono mostrare nulla, perché non sanno quale tipo sarà il parametro. L'analisi del codice non può cercare avvisi.

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

Questo ha un certo senso. Altri siti di chiamata potrebbero passare qualsiasi cosa per quel parametro. Ma se il mio metodo prevede che un parametro sia di tipo, diciamo, pygame.Surfacemi piacerebbe essere in grado di indicarlo a PyCharm in qualche modo, quindi può mostrarmi tutti Surfacegli attributi nel suo elenco a discesa di completamento del codice e evidenziare gli avvisi se Chiamo il metodo sbagliato, e così via.

C'è un modo in cui posso dare un suggerimento a PyCharm e dire "psst, questo parametro dovrebbe essere di tipo X"? (O forse, nello spirito dei linguaggi dinamici, "questo parametro dovrebbe ciarlare come una X"? Starei bene con quello.)


EDIT: la risposta di CrazyCoder, di seguito, fa il trucco. Per tutti i nuovi arrivati ​​come me che desiderano un breve riepilogo, eccolo qui:

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 parte rilevante è la @type peasant: Personlinea della dotstring.

Se vai anche su File> Impostazioni> Strumenti integrati di Python e imposti "Formato Docstring" su "Epytext", la vista Visualizzazione rapida> Documentazione di PyCharm stamperà piuttosto le informazioni sui parametri invece di stampare tutte le linee @ così come sono.


7
Va notato che il commento di reStructuredText utilizza gli stessi tag appena scritti in modo diverso: @param xx: yyydiventa :param xx: yyy. Vedi jetbrains.com/pycharm/webhelp/…
Wernight il

1
Perché possiamo evitare di non specificare il nome completo della classe?
Jesvin Jose,

Risposte:


85

Sì, è possibile utilizzare un formato di documentazione speciale per i metodi e i loro parametri in modo che PyCharm possa conoscere il tipo. La versione recente di PyCharm supporta i formati di documenti più comuni .

Ad esempio, PyCharm estrae i tipi dai commenti in stile @param .

Vedi anche convenzioni reStructuredText e docstring (PEP 257).

Un'altra opzione sono le annotazioni di Python 3.

Fare riferimento alla sezione della documentazione di PyCharm per maggiori dettagli e esempi.


2
Penso che PyCharm abbia cambiato un po 'il suo formato doc (vedi jetbrains.com/help/pycharm/… ), ma grazie! La mancanza di intellisense sui parametri mi stava facendo impazzire.
tronca il

46

Se si utilizza Python 3.0 o versioni successive, è anche possibile utilizzare le annotazioni su funzioni e parametri. PyCharm interpreterà questi come il tipo che gli argomenti oi valori di ritorno dovrebbero avere:

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

A volte questo è utile per i metodi non pubblici, che non necessitano di una docstring. Come ulteriore vantaggio, è possibile accedere a queste annotazioni tramite il codice:

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

Aggiornamento : A partire da PEP 484 , che è stato accettato per Python 3.5, è anche la convenzione ufficiale per specificare argomenti e tipi di ritorno usando le annotazioni.


4
... e ci sono diversi pacchetti che usano tali anntoations per eseguire il controllo del tipo di runtime. Questo è sia più comodo da usare che più facile da leggere rispetto a fare lo stesso con asserzioni e può essere usato selettivamente lo stesso. typecheck-decoratorè uno di questi pacchetti e ha una sintesi degli altri nella sua documentazione. (Anche flessibile: puoi persino fare la tipizzazione con anatra a controllo di tipo!)
Lutz Prechelt,

5

PyCharm estrae i tipi da una stringa pydoc @type. Consulta i documenti PyCharm qui e qui e i documenti Epydoc . È nella sezione "legacy" di PyCharm, forse manca di funzionalità.

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 parte rilevante è la @type peasant: Personlinea della dotstring.

La mia intenzione non è quella di rubare punti da CrazyCoder o dall'interrogatore originale, in ogni caso dare loro i loro punti. Pensavo solo che la risposta semplice dovesse trovarsi in uno slot di "risposta".


2

Sto usando PyCharm Professional 2016.1 scrivendo il codice py2.6-2.7 e ho scoperto che usando reStructuredText posso esprimere i tipi in un modo più succinto:

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.

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


1

Puoi anche affermare un tipo e Pycharm lo inferirà:

def my_function(an_int):
    assert isinstance(an_int, int)
    # Pycharm now knows that an_int is of type int
    pass
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.