Làm cách nào để sử dụng autodoc của Sphinx để ghi lại phương thức __init __ (self) của một lớp?


107

Sphinx không tạo tài liệu cho __init __ (self) theo mặc định. Tôi đã thử những cách sau:

.. automodule:: mymodule
    :members:

..autoclass:: MyClass
    :members:

Trong conf.py, cài đặt sau chỉ nối chuỗi doc_init __ (self) vào chuỗi docstring của lớp ( tài liệu tự động mã Sphinx dường như đồng ý rằng đây là hành vi mong đợi, nhưng không đề cập gì đến vấn đề tôi đang cố gắng giải quyết):

autoclass_content = 'both'

Không, đó không phải là những gì tài liệu viết cho đến ngày hôm nay, ít nhất là: "both" Both the class’ and the __init__ method’s docstring are concatenated and inserted.-> Vì vậy, nó không chỉ là __init__(self)mà còn là docstring của lớp nếu bạn có. Bạn có thể cung cấp một trường hợp kiểm tra vì nếu nó là như vậy, nó giống như một lỗi, phải không?
lpapp

Câu trả lời:


116

Dưới đây là ba lựa chọn thay thế:

  1. Để đảm bảo điều đó __init__()luôn được ghi lại, bạn có thể sử dụng autodoc-skip-membertrong conf.py. Như thế này:

    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)

    Điều này xác định rõ ràng __init__không được bỏ qua (theo mặc định). Cấu hình này được chỉ định một lần và nó không yêu cầu bất kỳ đánh dấu bổ sung nào cho mọi lớp trong nguồn .rst.

  2. Các special-memberstùy chọn được thêm vào trong Sphinx 1.1 . Nó làm cho các thành viên "đặc biệt" (những người có tên như__special__ ) được ghi lại bằng autodoc.

    Kể từ Sphinx 1.2, tùy chọn này nhận các đối số làm cho nó hữu ích hơn so với trước đây.

  3. Sử dụng automethod:

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

    Điều này phải được thêm vào cho mọi lớp (không thể được sử dụng với automodule, như đã chỉ ra trong nhận xét cho bản sửa đổi đầu tiên của câu trả lời này).


7
Điều đó không hữu ích với tự động hóa vì nó phải được thêm vào mọi lớp.
Roger Binns,

3
Giải pháp thay thế đầu tiên đã hoạt động. Trong trường hợp của tôi, nó tốt hơn so với lựa chọn thay thế thứ hai và thứ ba, vì nó không cần phải chỉnh sửa tệp .rst.
jcarballo

9
Trong Sphinx 1.2.1, special-membershoạt động tốt khi sử dụng automodule. Chỉ sử dụng :special-members: __init__để làm tài liệu __init__.
Florian Brucker

67

Bạn đã gần. Bạn có thể sử dụng autoclass_contenttùy chọn trong conf.pytệp của mình :

autoclass_content = 'both'

1
@MichaelMrozek: Tôi cũng đang thắc mắc về điều đó ... Bạn có hiểu tỷ lệ ủng hộ cao của câu trả lời này không? Lúc đầu, nó giống như một câu trả lời nên được loại bỏ.
lpapp

1
Tôi đã thử đặt autoclass_content = 'both'tùy chọn, tùy chọn này đã ghi lại phương thức init , nhưng nó làm cho bản ghi tự động xuất hiện hai lần.
Kéo dài

Đây phải là câu trả lời được chấp nhận. Nó đơn giản hơn và nó đề cập đến tài liệu chính thức về nhân sư.
BerriJ

6

Trong những năm qua, tôi đã viết một số biến thể của lệnh autodoc-skip-membergọi lại cho các dự án Python không liên quan khác nhau vì tôi muốn các phương thức như __init__(), __enter__()__exit__() để hiển thị trong tài liệu API của tôi (sau khi tất cả, những "phương pháp đặc biệt" là một phần của API và những gì nơi tốt hơn để ghi lại chúng hơn bên trong docstring của phương thức đặc biệt).

Gần đây, tôi đã thực hiện tốt nhất và biến nó thành một trong những dự án Python của tôi ( đây là tài liệu ). Việc triển khai về cơ bản là:

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

Có, có nhiều tài liệu hơn logic :-). Ưu điểm của việc xác định một lệnh autodoc-skip-membergọi lại như thế này so với việc sử dụng special-memberstùy chọn (đối với tôi) là special-memberstùy chọn này cũng cho phép tạo tài liệu về các thuộc tính như __weakref__(có sẵn trên tất cả các lớp kiểu mới, AFAIK) mà tôi cho là nhiễu và không hữu ích chút nào. Phương pháp gọi lại tránh điều này (vì nó chỉ hoạt động trên các hàm / phương thức và bỏ qua các thuộc tính khác).


Làm cách nào để sử dụng cái này? Có vẻ như phương thức phải được đặt tên setup(app)để được Sphinx thực thi.
oarfish

Tôi không hiểu hết, nhưng hãy xem cách thực hiện của xolox nếu bạn muốn tự mổ xẻ. Tôi tin rằng anh ấy đã xây dựng một tiện ích mở rộng nhân sư kết nối cuộc gọi lại với sự kiện thành viên tự động bỏ qua. Khi sphinx cố gắng tìm ra thứ gì đó nên được đưa vào / bỏ qua thì sự kiện đó sẽ kích hoạt và mã của anh ấy chạy. Nếu mã của anh ta phát hiện một thành viên đặc biệt đã được người dùng xác định rõ ràng (kế thừa như thường xảy ra) thì nó sẽ yêu cầu Sphinx bao gồm nó. Bằng cách đó bạn có thể các thành viên đặc biệt doc bạn viết cho mình
Andrew

Cảm ơn Andrew đã làm rõ và vâng, bạn là oarfish chính xác, một chức năng thiết lập là cần thiết. Tôi đã thêm nó vào ví dụ để tránh nhầm lẫn thêm.
xolox

@JoelB: Mã ví dụ trong bài đăng của tôi được viết để giả định rằng __init__phương thức của bạn có một chuỗi tài liệu rỗng. Phải không?
xolox

2

Mặc dù đây là một bài đăng cũ hơn, nhưng đối với những người đang tìm kiếm nó, cũng có một giải pháp khác được giới thiệu trong phiên bản 1.8. Theo tài liệu , Bạn có thể thêm special-memberkhóa trong autodoc_default_options vàoconf.py .

Thí dụ:

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

0

Đây là một biến thể chỉ bao gồm __init__nếu nó có các đối số:

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.