Подтвердить что ты не робот

Как указать, что параметр представляет собой список конкретных объектов в докстроках Python

Мне очень нравится использовать docstrings в Python для указания параметров типа, когда проекты превышают определенный размер.

У меня возникли проблемы с поиском стандарта для использования, чтобы указать, что параметр представляет собой список конкретных объектов, например. в типах Haskell я бы использовал [String] или [A].

Текущий стандарт (распознаваемый редактором PyCharm):

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

Что бы я предпочел:

ВАРИАНТ 1

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

ВАРИАНТ 2

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

Я полагаю, что это не был отличный пример - более подходящим вариантом использования будет тот, где объекты в списке должны быть определенного типа.

ЛУЧШИЙ ПРИМЕР

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

Итак, кроме того, что я проголодался, этот пример иллюстрирует, что если вызвано со списком неправильного типа объекта, код сломается. Отсюда важность документирования не только того, что ему нужен список, но и того, что ему нужен список продуктов питания.

СВЯЗАННЫЙ ВОПРОС Как я могу указать PyCharm, какой тип параметра должен быть? Обратите внимание, что я ищу более конкретный ответ, чем тот, который указан выше.

4b9b3361

Ответ 1

В разделе комментариев руководства PyCharm есть хороший намек от разработчика:

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

Это работает для меня довольно хорошо. Теперь мне интересно, что лучший способ документировать параметризованные классы в Python:).

Ответ 2

в python

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

вы также можете добавить строку в список int.

Итак, для того, что вы пытаетесь достичь PyCharm, вам придется волшебным образом проверить весь ваш код на то, что вы добавляете в список, прежде чем передавать его в качестве аргумента.

Вы можете взглянуть на этот вопрос Python: определить список определенного типа объекта

Однако модуль массива допускает только "базовые значения".

Единственное решение, о котором я могу думать, это создать свой собственный класс, который расширяет список python "FoodsList", который может проверять тип перед добавлением элемента.

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

При написании docstrings в стиле google вы можете сделать:

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

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

    """
    ...

Это также отлично работает в сфинксе, в сочетании с расширением наполеона. Дополнительную информацию о документации см. В документе расширения.

Ответ 4

Как указано в документации по PyCharm, (старый, pre- PEP-484) способ сделать это - использовать квадратные скобки:

list [Foo]: список элементов Foo

dict [Foo, Bar]: Дикт от Foo к бару

list of str, как предлагается в принятом ответе, не работает должным образом в PyCharm.

Начиная с Python 3.5 и реализации PEP-484, вы также можете использовать подсказки типов, которые могут быть приятно поддержаны вашей IDE/редактором. Как это легко сделать в PyCharm, объясняется здесь.

По сути, чтобы объявить тип возвращаемого списка с помощью type-hinting (Python> = 3.5), вы можете сделать что-то вроде этого:

from typing import List

"""
Great foo function.

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

Здесь мы объявляем (несколько избыточно), что функция foo возвращает список строк как в подсказке типа -> List[str] и в docstring :rtype: list[str].

Другие pre- объявленные типы и дополнительная информация могут быть найдены в документации Python для ввода.