Link para o método de classe em docstring python

87

Eu quero adicionar um link para um método em minha classe de dentro da docstring de outro método da mesma classe. Eu quero que o link funcione no sphinx e preferencialmente também no Spyder e em outros Python IDE.

Tentei várias opções e encontrei apenas uma que funciona, mas é complicado.

Suponha que a seguinte estrutura em mymodule.py

def class MyClass():
    def foo(self):
        print 'foo'
    def bar(self):
        """This method does the same as <link to foo>"""
        print 'foo'

Tentei as seguintes opções para <link to foo>:

  • : func: `foo`
  • : func: `self.foo`
  • : func: `MyClass.foo`
  • : func: `mymodule.MyClass.foo`

O único que efetivamente produz um link é: func: `mymodule.MyClass.foo`, mas o link é mostrado como mymodule.MyClass.foo()e eu quero um link que é mostrado como foo()ou foo.
Nenhuma das opções acima produz um link no Spyder.

Obrigado pela ajuda.

Saroele
fonte
O que significa "adicionar ... de dentro" ??? Qual é a diferença entre um link e um hiperlink?
eyquem de
Substituí hyperlinkpor linkpara evitar confusão.
saroele
Ainda não entendi muito bem sua pergunta. Você quer dizer que deseja realizar, do Sphinx ou do Spyder ou de outros IDEs Python, uma interrogação da docstring da função barque fornecerá a informação "a função ou método que você pesquisa é foo" ?
eyquem de
Em segundo lugar, que diferença você faz entre mymodule.MyClass.foo()e foo()? E o que você chama de "display" ? É a exibição de uma corda? Ou você quer um objeto devolvido? Neste último caso, os paens no final de mymodule.MyClass.foo()e foo()são demais.
eyquem de
Desculpe pela confusão, sempre é difícil explicar uma pergunta de forma concisa. Eu só quero ter um link em que você possa clicar, que o levará para a docstring de foo () (na janela de documentação do IDE, ou na construção html do Sphinx). Em relação aos parênteses: eles estão corretos:: func: mymodule.MyClass.fooresultou no link tendo parênteses. E eu reformulei a pergunta ligeiramente novamente.
saroele

Respostas:

88

A solução que funciona para o Sphinx é prefixar a referência com ~.

De acordo com a documentação do Sphinx sobre a sintaxe de referência cruzada ,

Se você prefixar o conteúdo com ~, o texto do link será apenas o último componente do destino. Por exemplo ~Queue.Queue.get,: py: meth: se referirá a Queue.Queue.get, mas exibirá apenas get como o texto do link.

Portanto, a resposta é:

class MyClass():
    def foo(self):
        print 'foo'
    def bar(self):
        """This method does the same as :func:`~mymodule.MyClass.foo`"""
        print 'foo'

Isso resulta em um html parecido com este: This method does the same as foo()e foo()é um link.

No entanto, observe que isso pode não ser exibido no Spyder como um link.

Saroele
fonte
15
( Spyder dev aqui ) @saroele Eu pretendo melhorar esta situação no futuro. Eu concordo totalmente que seria muito legal tê-lo;)
Carlos Cordoba
Isso é realmente ótimo, estou ansioso por isso. Obrigado por todo o seu trabalho no Spyder!
saroele
Você pode fazer isso com a :any:função - consulte a nota sobre default_setting.
naught101
1
é possível fazer referência cruzada sem usar o caminho completo do módulo?
Jonathan
2
Em vez de :func:, descobri que tinha que ser :meth:.
Leo Fang
37

Se você deseja especificar manualmente o texto do link, pode usar:

:func:`my text <mymodule.MyClass.foo>`

Para obter mais informações, consulte Referência cruzada de objetos Python .

devin_s
fonte
Isso funciona, obrigado. Olhando o link, descobri que prefixar a referência com ~está mais perto do que eu preciso. Eu coloquei isso em uma resposta separada. Ainda não funciona no Spyder, no entanto ...
saroele
-4

Parece-me que basta adicionar __name__ou __doc__à sua expressão para obter o que deseja.
Ainda não tenho certeza de ter entendido corretamente o objetivo

class MyClass():
    def foo(self):
        """I am the docstring of foo"""
        print 'foo'
    def bar(self):
        """This method does the same as <link to foo>"""
        print 'foo'

print
print MyClass.foo
print MyClass.foo.__name__
print MyClass.foo.__doc__
print
print MyClass.__dict__['foo']
print MyClass.__dict__['foo'].__name__
print MyClass.__dict__['foo'].__doc__

resultado

<unbound method MyClass.foo>
foo
I am the docstring of foo

<function foo at 0x011C27B0>
foo
I am the docstring of foo
eyquem
fonte
1
Eu acho que você perdeu o ponto da questão: Eu quero ter um link (hiperlink) no html da minha documentação construída pelo Sphinx.
saroele
Você está certo, eu não entendi. E isso porque não conheço a Esfinge. então tentei instalar o Sphinx. Mas não tive sucesso. Estou no Windows e tentei usar o sphinx-quickstart como dito no doc. Mas acho que entendi mal o processo de instalação. Eu não posso te ajudar, desculpe. Não sei o que deve ser entendido por 'hiperlink' no contexto do Sphinx.
eyquem de