如何为从其他模块导入的类进行文档注释 - 而不包含声明模块的名称?

20 投票
4 回答
5011 浏览
提问于 2025-04-17 17:19

我正在记录的这个包包含了一些 *.py 文件,大部分文件里都有一个类,还有一些文件是真正的模块,里面定义了一些函数。我不想让用户知道每个类都在一个模块里,所以我在 __init__.py 文件里添加了合适的 from 语句,比如:

from base import Base

这样用户就可以用 import pkg 命令,而不需要指定包含类的模块:

import pkg

class MyBase(pkg.Base):  # instead of pkg.base.Base ...
...

问题是,Sphinx(一个文档生成工具)坚持要把这个类显示为 pkg.base.Base。我尝试在 conf.py 文件里设置 add_module_names = False,但是这样做的结果是,Sphinx只显示类为 Base,而不是 pkg.Base。而且,这样还会搞乱那些确实是模块的 *.py 文件的文档。

我该如何让 Sphinx 显示类为 pkg.Base?还有,我该如何对每个 *.py 文件单独设置 add_module_names 指令?

4 个回答

1

我想提供一个更通用的方法。

这个变量 __all__ 是根据 dir() 的结果来填充的。不过,子包的名字(这里是 mypackage)和所有以 __ 开头的内置属性都会被忽略。

from .mypackage import *

__all__ = []
for v in dir():
    if not v.startswith('__') and v != 'mypackage':
        __all__.append(v)
1

我把找到的答案整理成了一种比较容易扩展的形式:

my_project/
    __init__.py
    mess.py
  • mess.py:
class MyClass:
    pass

class MyOtherClass(MyClass):
    pass
  • __init__.py:
from .mess import MyClass, MyOtherClass

__all_exports = [MyClass, MyOtherClass]

for e in __all_exports:
    e.__module__ = __name__

__all__ = [e.__name__ for e in __all_exports]

这对我来说似乎效果不错。

15

这里有一种方法可以实现提问者想要的效果:

  1. pkg/__init__.py 文件中添加一个 __all__ 列表:

    from base import Base    # Or use 'from base import *'
    
    __all__ = ["Base"]
    
  2. 在 .rst 文件中使用 .. automodule:: pkg

这样,Sphinx 生成的文档中,类名将显示为 pkg.Base,而不是 pkg.base.Base

撰写回答