Более 1 строки документации для одного модуля / функции и т. Д.? - PullRequest
4 голосов
/ 13 февраля 2010

Я использую Python 3.1.

Можно ли создать более 1 строки документации для одного модуля или функции? Я создаю программу и собираюсь создать несколько строк документации с категориями для каждой. Я намерен дать другим людям программу, чтобы они могли ее использовать, и чтобы упростить задачу для программистов и непрограммистов, я помещаю ссылку на строку документации для документации в самой программе.

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

например. Первая строка документации содержит инструкции по использованию программы. Вторая строка документации содержит информацию о том, как работает одна часть программы. Третья строка документации содержит информацию о том, как работает другая часть. и т.д.

Возможно ли это? И если да, то как вы на них ссылаетесь?

Обновления: добавлен комментарий.

Моя первоначальная мысль заключалась в том, чтобы на самом деле иметь более одной строки документации в смысле:

def foo():
    """docstring1: blah blah blah"""
    """docstring2: blah blah blah"""
    pass # Insert code here

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

Ответы [ 5 ]

4 голосов
/ 13 февраля 2010

Я не рекомендую пытаться делать что-то сложное с последовательностями документов.Лучше сохранять простоту строк документации и делать что-то еще, если вы хотите сделать доступными несколько различных вариантов документации.

Если вы действительно хотите сделать то, что вы описали, я предлагаю вам использовать теги для разделения разделов внутри строк документации,Вот так:

def foo(bar, baz):
    """Function foo()

* Summary:
    Function foo() handles all your foo-ish needs.  You pass in a bar and a baz and it foos them.

* Developers:
    When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests.

* Testers:
    When you test foo, be sure to try negative values for baz.
"""
    pass # code would go here

Тогда вы можете довольно легко разбить вашу строку на куски, и когда пользователь выбирает пункт меню, показывать только соответствующие куски.

s = foo.__doc__  # s now refers to the docstring

lst = s.split("\n* ")
section = [section for section in lst if section.startswith("Developers")][0]
print(section) # prints the "Developers" section

Таким образом,когда вы работаете в интерактивной оболочке Python, вы можете сказать «help (foo)», и вы увидите все строки документации.И вы не изменяете фундаментальное поведение базовой части Python, что пугало бы других людей, пытающихся изучить ваш код.

Вы также можете сделать что-то еще проще: просто создайте большой глобальный словарь строк документациидля различных целей и обновлять его из исходного кода для каждой новой вещи.

doc_developers = {} doc_testers = {}

def foo(bar, baz):
    """Function foo()

Function foo() handles all your foo-ish needs.  You pass in a bar and a baz and it foos them."
    pass # code goes here

doc_developers["foo"] = "When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests."

doc_testers["foo"] = "When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests."

Самое большое, что мне не нравится в этом, эточто если вы измените имя функции foo, вам нужно будет изменить его в нескольких местах: один раз в фактическом def и один раз в строке обновления словаря.Но в основном это можно исправить, написав функцию:

def doc_dict = {} # this will be a dict of dicts
doc_dict["developers"] = {}
doc_dict["testers"] = {}

def doc_update(fn, d):
    name = fn.__name__
    for key, value in d.items():
        doc_dict[key][name] = value

def foo(bar, baz):
    """Function foo()

Function foo() handles all your foo-ish needs.  You pass in a bar and a baz and it foos them."
    pass # code goes here

d = { "developers": "When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests.",
"testers": " When you test foo, be sure to try negative values for baz."}

doc_update(foo, d)

Вероятно, есть способ превратить doc_update () в декоратор, но сейчас у меня нет времени.

3 голосов
/ 13 февраля 2010

Вы хотите рассмотреть возможность использования декораторов , чтобы сделать чисто то, что предлагает ~ unutbu для функций: добавление отдельного поля для каждого. Например:

def human_desc(description):
    def add_field(function):
        function.human_desc = description
        return function
    return add_field

Вот как human_desc в действии будет выглядеть:

@human_desc('This function eggfoobars its spam.')
def eggfoobar(spam):
    "Apply egg, foo and bar to our spam metaclass object stuff."
    print spam

Explaination

Как документ объясняет , этот бит кода эквивалентен следующему:

def eggfoobar(spam):
    "Apply egg, foo and bar to our spam metaclass object stuff."
    print spam
eggfoobar = human_desc('This function eggfoobars its spam.')(eggfoobar)

и human_desc('This function eggfoobars its spam.') возвращает следующую функцию:

def add_field(function):
    function.human_desc = 'This function eggfoobars its spam.'
    return function

Как видите, human_desc - это функция, которая генерирует описанный выше декоратор для значения description, которое вы передаете в качестве аргумента. Сам декоратор - это функция, которая принимает функцию, которая должна быть декорирована (изменена), и возвращает ее декорированную (в данном случае, то есть с добавлением этого дополнительного метаданных). Вкратце это эквивалентно:

def eggfoobar(spam):
    "Apply egg, foo and bar to our spam metaclass object stuff."
    print spam
eggfoobar.human_desc = 'This function eggfoobars its spam.'

Синтаксис, однако, намного чище и менее подвержен ошибкам.

Очевидно, что в любом случае вы получите:

>>> print eggfoobar.human_desc
This function eggfoobars its spam.
2 голосов
/ 13 февраля 2010

Вместо использования функции вы можете использовать класс с определенными атрибутами usage и extra. Например,

class Foo(object):
    '''Here is the function's official docstring'''
    usage='All about the usage'
    extra='How another part works'
    def __call__(self):
        # Put the foo function code here
        pass
foo=Foo()

Вы бы назвали это как обычно: foo(), и вы можете получить официальную строку документации и альтернативную строку документа следующим образом:

print foo.__doc__
print foo.usage
print foo.extra

Вы также можете прикрепить дополнительные атрибуты к простым функциям (вместо использования класса, как я делал выше), но я думаю, что синтаксис немного уродливее:

def foo():
    pass
foo.usage='Usage string'
foo.extra='Extra string'

И, модули тоже объекты. Они могут иметь дополнительные атрибуты так же легко:

Если вы определяете константы модуля

USAGE='''blah blah'''
EXTRA='''meow'''

Затем при импорте модуля:

import mymodule

Вы можете получить доступ к официальным и альтернативным строкам документов с помощью

mymodule.__doc__
mymodule.USAGE
mymodule.EXTRA
0 голосов
/ 13 февраля 2010

Модуль представляет собой набор классов / функций / модулей. Так что его строка документации дает представление о том, что она содержит.

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

Функции делают одну вещь, поэтому для них должно хватить одной доктрины.

Я не вижу, для какой цели будет достаточно нескольких строк документации. Может быть, ваш модуль большой. Разделите на подмодули и в строке документации для упомянутых подмодулей модуля.

0 голосов
/ 13 февраля 2010

Вы можете заменить атрибут __doc__, если хотите иметь более одной возможной строки документации, но, пожалуйста, рассмотрите возможность сделать исходную строку документации достаточно гибкой для всех типов.

...