web-dev-qa-db-fra.com

Comment spécifier qu'un paramètre est une liste d'objets spécifiques dans Python docstrings

J'aime vraiment utiliser docstrings dans Python pour spécifier les paramètres de type lorsque les projets dépassent une certaine taille.

J'ai du mal à trouver une norme à utiliser pour spécifier qu'un paramètre est une liste d'objets spécifiques, par exemple dans les types Haskell, j'utiliserais [String] ou [A].

Norme actuelle (reconnaissable par l'éditeur PyCharm):

def stringify(listOfObjects):
    """
    :type listOfObjects: list
    """
    return ", ".join(map(str, listOfObjects))

Ce que je préfère:

OPTION 1

def stringify(listOfObjects):
    """
    :type listOfObjects: list<Object>  
    """
    return ", ".join(map(str, listOfObjects))

OPTION 2

def stringify(listOfObjects):
    """
    :type listOfObjects: [Object]
    """
    return ", ".join(map(str, listOfObjects))

Je suppose que ce n'était pas un excellent exemple - le cas d'utilisation le plus pertinent serait celui où les objets de la liste doivent être d'un type spécifique.

MEILLEUR EXEMPLE

class Food(Object):
    def __init__(self, calories):
        self.calories = calories

class Apple(Food):
    def __init__(self):
        super(self, 200)

class Person(Object):
    energy = 0
    def eat(foods):
        """
        :type foods: [Food]  # is NOT recognised by editor
        """
        for food in foods:
            energy += food.calories

Donc, à part le fait que j'ai faim, cet exemple illustre que s'il était appelé avec une liste du mauvais type d'objet, le code se briserait. D'où l'importance de documenter non seulement qu'il a besoin d'une liste, mais qu'il a besoin d'une liste de nourriture.

QUESTION ASSOCIÉE Comment puis-je dire à PyCharm de quel type un paramètre est censé être? Veuillez noter que je recherche un réponse plus précise que celle ci-dessus.

42
Alex

Dans la section commentaires de manuel de PyCharm il y a un bon indice du développeur:

#: :type: dict of (str, C)
#: :type: list of str

Cela fonctionne assez bien pour moi. Maintenant, je me demande quelle est la meilleure façon de documenter les classes paramétrées dans Python :).

49
Michael Korbakov

en python

type([1,2,3]) == type(['a', 'b', 'c'])

vous pouvez également ajouter une chaîne à la liste des entiers.

Donc, pour ce que vous essayez d'atteindre, PyCharm devrait vérifier par magie tout votre code pour ce que vous ajoutez à la liste avant de le passer en argument.

Vous pouvez jeter un oeil à cette question Python: définir une liste d'un type d'objet spécifique

Le module Array n'autorise cependant que les "valeurs de base".

La seule solution à laquelle je peux penser ici est de créer votre propre classe qui étend python list "FoodsList" qui peut vérifier le type avant d'ajouter un élément.

class Food():
    def __init__(self, calories):
        self.calories = calories

class FoodsList(list):
    #you can optionally extend append method here to validate type
    pass

def eat(foods):
    """
    :type foods: FoodsList
    """
    energy = 0
    for food in foods:
        energy += food.calories
    return energy


list = FoodsList()
list.append(Food(3))
list.append(Food(4))
print eat(list)
3
fsw

Lorsque vous écrivez des docstrings dans le style google, vous pouvez faire:

class ToDocument(object):
    """This is my Documentation.

    Args:
        typed_list (:obj:`list` of :obj:`str`): Description of typed list

    """
    ...

Cela fonctionne également très bien dans le sphinx, lorsqu'il est combiné avec l'extension napoléon. Reportez-vous au doc de l'extension pour plus d'exemples sur la documentation.

1
Kim

Comme indiqué dans les documents PyCharm , a (hérité, pré - PEP-484 ) Pour ce faire, utilisez des crochets:

list [Foo]: Liste des éléments Foo

dict [Foo, Bar]: Dict de Foo à Bar

list of str, comme suggéré dans la réponse acceptée , ne fonctionne pas comme prévu dans PyCharm.

En commençant par Python 3.5 et l'implémentation de PEP-484 , vous pouvez également utiliser des indices de type, qui peuvent être bien pris en charge par votre IDE/éditeur. Comment cela est-il facile? fait dans PyCharm est expliqué ici .

En substance, pour déclarer un type de retour de liste en utilisant l'indication de type (Python> = 3.5), vous pouvez faire quelque chose comme ceci:

from typing import List

"""
Great foo function.

:rtype: list[str]
"""
def foo() -> List[str]:
    return ['some string', 'some other string']

Ici, nous déclarons (quelque peu de manière redondante) que la fonction foo renvoie une liste de chaînes, toutes deux dans le type hint -> List[str] et dans la docstring :rtype: list[str].

D'autres types pré-déclarés et plus d'informations peuvent être trouvés dans les documents Python pour typage .

0
hendrik