Bagaimana cara menggunakan autodoc Sphinx untuk mendokumentasikan metode __init __ (self) kelas?

107

Sphinx tidak membuat dokumen untuk __init __ (self) secara default. Saya telah mencoba yang berikut ini:

.. automodule:: mymodule
    :members:

dan

..autoclass:: MyClass
    :members:

Di conf.py, pengaturan berikut hanya menambahkan docstring __init __ (self) ke kelas docstring ( dokumentasi autodoc Sphinx sepertinya setuju bahwa ini adalah perilaku yang diharapkan, tapi tidak menyebutkan apapun mengenai masalah yang saya coba selesaikan):

autoclass_content = 'both'
Jacob Marble
sumber
Tidak, bukan itu yang ditulis oleh dokumentasi pada hari ini, setidaknya: "both" Both the class’ and the __init__ method’s docstring are concatenated and inserted.-> Oleh karena itu, seharusnya tidak hanya menjadi __init__(self), tetapi juga kelas docstring jika Anda memilikinya. Bisakah Anda memberikan test case karena jika demikian, rasanya seperti bug, bukan?
lpapp

Jawaban:

116

Berikut tiga alternatif:

  1. Untuk memastikan bahwa __init__()selalu didokumentasikan, Anda dapat menggunakan autodoc-skip-memberdi conf.py. Seperti ini:

    def skip(app, what, name, obj, would_skip, options):
        if name == "__init__":
            return False
        return would_skip
    
    def setup(app):
        app.connect("autodoc-skip-member", skip)
    

    Ini secara eksplisit mendefinisikan __init__untuk tidak dilewati (yang secara default). Konfigurasi ini ditentukan sekali, dan tidak memerlukan markup tambahan untuk setiap kelas di sumber .rst.

  2. The special-memberspilihan yang ditambahkan dalam Sphinx 1.1 . Itu membuat anggota "khusus" (mereka yang memiliki nama seperti __special__) didokumentasikan oleh autodoc.

    Sejak Sphinx 1.2, opsi ini membutuhkan argumen yang membuatnya lebih berguna daripada sebelumnya.

  3. Penggunaan automethod:

    .. autoclass:: MyClass     
       :members: 
    
       .. automethod:: __init__
    

    Ini harus ditambahkan untuk setiap kelas (tidak dapat digunakan dengan automodule, seperti yang ditunjukkan dalam komentar pada revisi pertama jawaban ini).

mzjn
sumber
7
Itu tidak membantu dengan automodule karena harus ditambahkan ke setiap kelas.
Roger Binns
3
Alternatif pertama berhasil. Dalam kasus saya, ini lebih baik daripada alternatif kedua dan ketiga, karena tidak perlu mengedit file .rst.
jcarballo
9
Di Sphinx 1.2.1, special-membersberfungsi dengan baik menggunakan automodule. Gunakan :special-members: __init__untuk mendokumentasikan saja __init__.
Florian Brucker
67

Anda sudah dekat. Anda dapat menggunakan autoclass_contentopsi di conf.pyfile Anda :

autoclass_content = 'both'
Gotgenes
sumber
1
@MichaelMrozek: Saya juga bertanya-tanya tentang itu ... Apakah Anda memahami tingkat upvote yang tinggi dari jawaban ini? Pada awalnya, sepertinya jawaban yang harus dihapus.
lpapp
1
Saya mencoba mengatur autoclass_content = 'both'opsi, yang mendokumentasikan metode init , tetapi itu membuat autosummary muncul dua kali.
Peregangan
Ini harus menjadi jawaban yang diterima. Ini lebih sederhana dan mengacu pada dokumentasi resmi sphinx.
BerriJ
6

Selama beberapa tahun terakhir saya telah menulis beberapa varian autodoc-skip-membercallback untuk berbagai proyek Python yang tidak terkait karena saya ingin metode seperti __init__(), __enter__()dan __exit__()muncul dalam dokumentasi API saya (bagaimanapun, "metode khusus" ini adalah bagian dari API dan tempat apa yang lebih baik untuk mendokumentasikannya daripada di dalam docstring metode khusus).

Baru-baru ini saya mengambil implementasi terbaik dan menjadikannya bagian dari salah satu proyek Python saya ( berikut dokumentasinya ). Implementasinya pada dasarnya bermuara pada ini:

import types

def setup(app):
    """Enable Sphinx customizations."""
    enable_special_methods(app)


def enable_special_methods(app):
    """
    Enable documenting "special methods" using the autodoc_ extension.

    :param app: The Sphinx application object.

    This function connects the :func:`special_methods_callback()` function to
    ``autodoc-skip-member`` events.

    .. _autodoc: http://www.sphinx-doc.org/en/stable/ext/autodoc.html
    """
    app.connect('autodoc-skip-member', special_methods_callback)


def special_methods_callback(app, what, name, obj, skip, options):
    """
    Enable documenting "special methods" using the autodoc_ extension.

    Refer to :func:`enable_special_methods()` to enable the use of this
    function (you probably don't want to call
    :func:`special_methods_callback()` directly).

    This function implements a callback for ``autodoc-skip-member`` events to
    include documented "special methods" (method names with two leading and two
    trailing underscores) in your documentation. The result is similar to the
    use of the ``special-members`` flag with one big difference: Special
    methods are included but other types of members are ignored. This means
    that attributes like ``__weakref__`` will always be ignored (this was my
    main annoyance with the ``special-members`` flag).

    The parameters expected by this function are those defined for Sphinx event
    callback functions (i.e. I'm not going to document them here :-).
    """
    if getattr(obj, '__doc__', None) and isinstance(obj, (types.FunctionType, types.MethodType)):
        return False
    else:
        return skip

Ya, ada lebih banyak dokumentasi daripada logika :-). Keuntungan mendefinisikan autodoc-skip-memberpanggilan balik seperti ini dibandingkan penggunaan special-membersopsi (bagi saya) adalah bahwa special-membersopsi tersebut juga mengaktifkan dokumentasi properti seperti __weakref__(tersedia di semua kelas gaya baru, AFAIK) yang menurut saya berisik dan tidak berguna sama sekali. Pendekatan callback menghindari ini (karena hanya bekerja pada fungsi / metode dan mengabaikan atribut lain).

xolox
sumber
Bagaimana cara menggunakan ini? Tampaknya metode tersebut harus diberi nama setup(app)agar dapat dijalankan oleh Sphinx.
oarfish
Saya tidak mengerti semuanya, tapi lihat implementasi xolox jika Anda ingin membedah diri sendiri. Saya yakin dia membuat ekstensi sphinx yang menghubungkan callback ke acara autodoc-skip-member. Ketika sphinx mencoba untuk mencari tahu apakah sesuatu harus disertakan / dilewati, peristiwa itu akan aktif, dan kodenya berjalan. Jika kodenya mendeteksi anggota khusus yang didefinisikan secara eksplisit oleh pengguna (diwariskan seperti yang sering terjadi) maka itu memberitahu Sphinx untuk memasukkannya. Dengan cara itu Anda dapat mendokumentasikan anggota khusus yang Anda tulis sendiri
Andrew
Terima kasih atas klarifikasi Andrew dan ya Anda benar oarfish, diperlukan fungsi pengaturan. Saya telah menambahkannya ke contoh untuk menghindari kebingungan lebih lanjut.
xolox
@ JoelB: Contoh kode di posting saya ditulis untuk mengasumsikan bahwa __init__metode Anda memiliki docstring tidak kosong. Melakukannya?
xolox
2

Meskipun ini adalah posting yang lebih lama, tetapi bagi mereka yang melihatnya seperti sekarang, ada juga solusi lain yang diperkenalkan di versi 1.8. Menurut dokumentasi , Anda dapat menambahkan special-memberkunci dalam autodoc_default_options ke conf.py.

Contoh:

autodoc_default_options = {
    'members': True,
    'member-order': 'bysource',
    'special-members': '__init__',
    'undoc-members': True,
    'exclude-members': '__weakref__'
}
dheinz
sumber
0

Ini adalah varian yang hanya disertakan __init__jika memiliki argumen:

import inspect

def skip_init_without_args(app, what, name, obj, would_skip, options):
    if name == '__init__':
        func = getattr(obj, '__init__')
        spec = inspect.getfullargspec(func)
        return not spec.args and not spec.varargs and not spec.varkw and not spec.kwonlyargs
    return would_skip

def setup(app):
    app.connect("autodoc-skip-member", skip_init_without_args)
letmaik
sumber