178 votes

Comment connaître le type de retour d'une fonction et les types d'arguments ?

Bien que je connaisse le concept de typage de Python, j'ai parfois du mal à déterminer le type des arguments des fonctions ou le type de la valeur de retour de la fonction.

Maintenant, si j'ai écrit la fonction moi-même, je connais les types. Mais si quelqu'un veut utiliser et appeler mes fonctions, comment est-il censé connaître les types ? J'ai l'habitude de mettre des informations sur les types dans la docstring de la fonction (comme : "...the id argument should be an integer..." y "... the function will return a (string, [integer]) tuple." )

Mais est-ce que chercher l'information dans la docstring (et la mettre là, en tant que codeur) est vraiment la façon dont cela doit être fait ?

Editer : Alors que la majorité des réponses semblent s'orienter vers "oui, document !", je pense que ce n'est pas toujours le cas. j'ai l'impression que ce n'est pas toujours très facile pour les types "complexes".
Par exemple : comment décrire de manière concise dans une docstring qu'une fonction renvoie une liste de tuples, chaque tuple étant de la forme (node_id, node_name, uptime_minutes) et que les éléments sont respectivement une chaîne de caractères, une chaîne de caractères et un nombre entier ?
La documentation PEP docstring ne donne aucune indication à ce sujet.
Je suppose que le contre-argument sera que dans ce cas les classes devraient être utilisées, mais je trouve python très flexible parce qu'il permet de passer ces choses en utilisant des listes et des tuples, c.-à-d. sans classes.

287voto

Rsh Points 939

Les choses ont un peu changé depuis 2011 ! Désormais, il y a indices de type dans Python 3.5, que vous pouvez utiliser pour annoter les arguments et renvoyer le type de votre fonction. Par exemple, ceci :

def greeting(name):
  return 'Hello, {}'.format(name)

peut maintenant s'écrire comme suit :

def greeting(name: str) -> str:
  return 'Hello, {}'.format(name)

Comme vous pouvez le voir maintenant, il y a une sorte de vérification de type statique optionnelle qui vous aidera, vous et votre vérificateur de type, à examiner votre code.

Pour plus d'explications, je vous suggère de jeter un coup d'œil à l'article de blog sur les conseils de type dans PyCharm blog .

27voto

PYC Points 161

En fait, ce n'est pas nécessaire car Python est un langage dynamique, MAIS Si vous souhaitez spécifier une valeur de retour, procédez comme suit

def foo(a) -> int: #after arrow type the return type 
       return 1 + a

Mais cela ne vous aidera pas beaucoup. Il ne soulève pas d'exceptions de la même manière que dans les langages à typage statique comme java, c, c++. Même si vous renvoyez une chaîne de caractères, aucune exception ne sera levée.

puis, pour le type d'argument, procédez comme suit

def foo(a: int) -> int:
      return a+ 1

après les deux points ( : ), vous pouvez spécifier le type d'argument. Cela ne sert à rien non plus, pour le prouver voici un exemple :

def printer(a: int) -> int: print(a)

printer("hello")

La fonction ci-dessus renvoie simplement None parce que nous n'avons rien renvoyé, mais nous lui avons dit que nous reviendrions int mais comme je l'ai dit, cela ne sert à rien. Peut-être que cela pourrait aider dans les IDE (pas tous mais quelques uns comme pycharm ou quelque chose comme ça, mais pas sur vscode )

25voto

Daren Thomas Points 26812

C'est ainsi que fonctionnent les langages dynamiques. Ce n'est cependant pas toujours une bonne chose, surtout si la documentation est médiocre - quelqu'un a-t-il essayé d'utiliser un framework python mal documenté ? Parfois, il faut revenir à la lecture des sources.

Voici quelques stratégies pour éviter les problèmes liés à la dactylographie des canards :

  • créer une langue pour votre domaine de problèmes
  • cela vous aidera à nommer les choses correctement
  • utiliser des types pour représenter des concepts dans le langage de votre domaine
  • nommer les paramètres des fonctions en utilisant le vocabulaire du langage du domaine

En outre, l'un des points les plus importants :

  • garder les données aussi locales que possible !

Il ne devrait y avoir que quelques types bien définis et documentés qui circulent. Tout le reste doit être évident en regardant le code : Ne pas avoir de types de paramètres bizarres qui viennent de loin et que l'on ne peut pas comprendre en regardant à proximité du code...

Dans le même ordre d'idées (et également en rapport avec les docstrings), il existe une technique en python appelée doctests . Utilisez-le pour documenter la façon dont vos méthodes sont censées être utilisées - et obtenez en même temps une bonne couverture des tests unitaires !

10voto

murarisumit Points 631

J'ai participé à un cours sur Coursera, où l'on nous a enseigné la recette du design.

Le format de docstring ci-dessous m'a semblé très utile.

def area(base, height):
    '''(number, number ) -> number    #\*\*TypeContract\*\*
    Return the area of a tring with dimensions base   #\*\*Description\*\*
    and height

    >>>area(10,5)          #\*\*Example \*\*
    25.0
    >>area(2.5,3)
    3.75
    '''
    return (base \* height) /2 

Je pense que si les documentations sont rédigées de cette manière, cela pourrait aider considérablement les développeurs.

Lien vers la vidéo [Voir la vidéo] : https://www.youtube.com/watch?v=QAPg6Vb_LgI

6voto

Rabarberski Points 4902

Pour répondre à ma propre question >10 ans plus tard, il y a maintenant 2 choses que j'utilise pour gérer cela :

  • indices de type (comme déjà mentionné dans d'autres réponses)
  • classes de données lorsque les indications relatives aux paramètres ou aux types de retour deviennent difficiles à comprendre ou à lire

Pour illustrer ce dernier point, disons que j'ai une fonction

def do_something(param:int) -> list[tuple[list, int|None]]:
   ...
   return result

Je réécrirais maintenant en utilisant une classe de données, par exemple en suivant les lignes suivantes :

from dataclasses import dataclass

@dataclass
class Stat:
    entries: list
    value: int | None = None

 def do_something(param:int) -> list[Stat]:
   ...
   return result

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X