Как ссылаться на документированный параметр функции Python с помощью разметки Sphinx?
Я хотел бы ссылаться на ранее зарегистрированный параметр функции в другом месте в docstring Python. Рассмотрим следующий (предположительно, полностью искусственный) пример:
def foo(bar):
"""Perform foo action
:param bar: The bar parameter
"""
def nested():
"""Some nested function that depends on enclosing scope bar parameter.
I'd like to reference function foo bar parameter here
with a link, is that possible?"""
return bar * bar
# ...
return nested()
Есть ли простой способ вставить ссылку на параметр с помощью разметки Sphinx, или это произойдет автоматически?
(Я полный новичок Sphinx. Я просматривал документы Sphinx и не нашел ответа на этот вопрос или пример, демонстрирующий правильную разметку.)
Ответы
Ответ 1
Я только что построил расширение для выполнения этой задачи. Пока что он работает с автономной сборкой HTML и, кроме того, с readthedocs (после некоторых дополнительных настроек).
расширение доступно по адресу: https://pypi.python.org/pypi/sphinx-paramlinks/.
Я сейчас развертываю это для проектов Alembic и SQLAlchemy. (образец).
Я не согласен с предположением, что ссылки на params означают, что документы слишком длинные. Стандартная библиотека Python - плохой пример, поскольку функции stdlib обязательно должны быть детальными и простыми. Программное обеспечение, которое выполняет более грубую задачу, в которой отдельная функция находится на вершине сложной проблемы, которая должна быть решена, часто имеет параметры, которые требуют гораздо большего объяснения; это объяснение часто весьма ценно, поскольку решение конкретной проблемы в другом месте, и, следовательно, возможность ссылки на него очень важно.
Ответ 2
Нет простого способа получить прямую ссылку на параметр функции с sphinx
, и я не знаю расширения для этой проблемы.
Документация
Ответ 3
Для тех, кто хочет использовать sphinx-paramlinks
с sphinx.ext.napoleon
, вот патч. Просто найдите нужный фрагмент в исходном коде sphinx-paramlinks
(sphinx_paramlinks\sphinx_paramlinks.py, где-то в строке 50) и замените его следующим:
def cvt(m):
directive, modifier, objname, paramname = (
m.group(1), m.group(2) or '', name, m.group(3))
if directive == 'param':
refname = _refname_from_paramname(paramname, strip_markup=True)
item = ('single', '%s (%s parameter)' % (refname, objname),
'%s.params.%s' % (objname, refname), '')
if LooseVersion(__version__) >= LooseVersion('1.4.0'):
item += (None,)
doc_idx.append(item)
return ":%s %s_sphinx_paramlinks_%s.%s:" % (
directive, modifier, objname, paramname)
return re.sub(r'^:(param|type) ([^:]+? )?([^:]+?):', cvt, line)
Примечание: помните о правильном отступе.
Я не специалист по Сфинксу, но это, кажется, делает работу.
Ответ 4
Если вы ищете способ прямого ссылки на определение bar
foo
, то ваша документация слишком длинна или вы просите вашего читателя игнорировать лес для одного дерева или некоторую комбинацию из двух.
Пример из defaultdict Примеры:
Setting the :attr:`default_factory` to :class:`int` makes the
:class:`defaultdict` useful for counting (like a bag or multiset in other
languages):
если мне не помешает прочитать пять предложений в collections.defaultdict, чтобы найти значение default_factory
Я, вероятно, не заслуживают того, чтобы их там проводили.
Обратите внимание, что синтаксис ссылки атрибута такой же, как в приведенном выше разделе:
The first argument provides the initial value for the :attr:`default_factory`
attribute; it defaults to ``None``.
но похоже, что Sphinx не выходит за пределы текущего раздела и поэтому делает более позднюю ссылку в виде стилизованного текста, а не как привязку. Меня это не удивило бы, если бы это было намеренно.