代码注释与文档生成工具: epydoc与doxygen

代码注释与文档生成工具: epydoc与doxygen

目录

1 前言2 epydoc2.1 安装2.2 常用方法2.3 配置文件2.4 epytext2.5 epydoc的相关项目2.6 完整举例3 doxygen3.1 模板3.2 样例3.3 安装3.4 开始使用3.5 如何注释代码3.6 常用标签命令3.7 特殊标记命令4 后记5 参考

1 前言

很多时候看别人代码,发现注释挺有风格,还挺统一,其实不但是为了方便读,更是为了方便自动生成文档。

毕竟,在代码堆里翻来覆去看注释也不太方便,在PDF或者HTML格式文档里面看更加方便、灵活。

epydoc 专门用于Python代码里面自动生成文档,而 doxygen 则广泛用于C++、Java、Python等代码里面自动生成文档。

当然,还有一个 Sphinx ,但这个还是比较适合于写用户手册,不太熟悉,自己写用户手册一般使用 Org-Mode

通过注释、文档嵌入代码的方式,既保持了文档能够及时更新,也方便维护。

这次的关注重点是 epydoc

2 epydoc

epydoc 是根据Python代码里面注释生成API文档的工具。

2.1 安装

下载源码 https://pypi.python.org/pypi/epydoc 进行安装:

$ cd epydoc-3.0.1$ sudo python setup.py install$ epydoc --help$ epydocgui
2.2 常用方法

为epydoc模块生成html文档,保存于doc目录:

$ epydoc --html epydoc -o doc$ epydoc --html epydoc/gui.py -o HTML

生成PDF文档:

$ epydoc -v -o PDF --pdf --name "Epydoc" epydoc/

检查文档信息:

$ epydoc --check epydoc/gui.py
2.3 配置文件

epydoc 可以通过 --config 指定配置文件,配置文件举例:

[epydoc] # Epydoc section marker (required by ConfigParser)# Information about the project.name: My Cool Projecturl: http://cool.project/# The list of modules to document.  Modules can be named using# dotted names, module filenames, or package directory names.# This option may be repeated.modules: sys, os.path, remodules: my/project/driver.py# Write html output to the directory "apidocs"output: htmltarget: apidocs/# Include all automatically generated graphs.  These graphs are# generated using Graphviz dot.graph: alldotpath: /usr/local/bin/dot
2.4 epytext

epydoc 支持的被标记的文档叫 epytext ,这是Python文档字符串中的一种轻量级标记语言。

2.4.1 段落

对于段落的要求就是 左对齐 ,左对齐的数行文本就是一个段落,举例:

Rendered Outputdef example():    """    This is a paragraph.  Paragraphs can    span multiple lines, and can contain    I{inline markup}.    This is another paragraph.  Paragraphs    are separated by blank lines.    """    [...]
2.4.2 列表

对于列表,分为排序和非排序,如果是排序则用 数字 开头,如果是非排序,则用 - 开头。

同时,在内容上要有一定的 缩进 ,这样才能形成有层次的列表, 举例:

def example():    """    1. This is an ordered list item.    2. This is a another ordered list    item.    3. This is a third list item.  Note that       the paragraph may be indented more       than the bullet.    """    [...]def example():    """    This is a paragraph.      1. This is a list item.      2. This a second list         item.           - This is a sublist    """    [...]def example():    """    This is a paragraph.      1. This is a list item.        - This is a sublist.        - The sublist contains two          items.            - The second item of the               sublist has its own sublist.      2. This list item contains two         paragraphs and a doctest block.         >>> print 'This is a doctest block'         This is a doctest block         This is the second paragraph.    """    [...]

另外, epytext 遇到数字或者 - 就会看做列表处理,如果要当成普通文本,则:

不要在开头或者转义字符

2.4.3 章节

章节依次下降:

=======-------~~~~~~~

举例:

def example():    """    This paragraph is not in any section.    Section 1    =========      This is a paragraph in section 1.      Section 1.1      -----------      This is a paragraph in section 1.1.      Section 1.1.1      ~~~~~~~~~~~~~      This is a paragraph in section 1.1.1    Section 2    =========      This is a paragraph in section 2.    """
2.4.4 文本块

对于在 :: 之后的文本是文本块,不会进行标记,直接显示内容:

def example():    """    The following is a literal block::        Literal /               / Block    This is a paragraph following the    literal block.    """    [...]

注意 文本块 内容是有一定的缩进的,否则会报错。

2.4.5 doctest块

doctest文档是可以模块 doctest 进行测试运行的内容,一般是在python解释器里面的操作内容:

def example():    """    The following is a doctest block:        >>> print (1+3,        ...        3+5)        (4, 8)        >>> 'a-b-c-d-e'.split('-')        ['a', 'b', 'c', 'd', 'e']    This is a paragraph following the    doctest block.    """
2.4.6 Field标签

针对具体的类、变量等文档标记:

def example():    """    @param x: This is a description of        the parameter x to a function.        Note that the description is        indented four spaces.    @type x: This is a description of        x's type.    @return: This is a description of        the function's return value.        It contains two paragraphs.    """

更多标记参考: http://www.ast.cam.ac.uk/~rgm/dazle/software/dics/src/epydoc-3.0alpha2/doc/fields.html#fields

Function docstrings:

@param p: …参数p的说明@type p: …参数p的类型@return: …函数的返回值@rtype: …函数的返回值类型@keyword p: …关键字参数p的说明@raise e: …函数内部的异常e的说明

Variables (module or class docstrings):

@ivar v: …类实例的变量v@cvar v: …类的静态变量v@var v: …模块变量v@type v: …变量v的类型

Properties (property docstrings):

@type: …属性类型

Grouping and Sorting (module, class, function, or method docstrings):

@group g: c1,…,cnOrganizes将相关的子模块、类组成一个组g@sort: c1,…,cnSpecifies组成员的排序

Related Topics:

@see: …关联内容

Notes and Warnings:

@note: …注解@attention: …警告@bug: …Bug@warning: …提醒

Status:

@version: …版本@todo [ver]: …计划@deprecated: …避免使用@since: …开始使用的日期或版本@status: …状态

Formal Conditions:

@requires: …使用对象依赖的条件@precondition: …条件判断为True才可以使用对象@postcondition: …对象使用条件应该判断为True@invariant: …对于对象,条件应该总是True

Bibliographic Information:

@author: …作者@organiation: …组织结构@copyright: …版权说明@license: …授权模式@contact: …联系方式

Summarization:

@summary: …总结内容
2.4.7 内嵌标记

最简单的内嵌标记I{...}: 斜体B{...}: 粗体C{...}: 代码M{...}: 数学表达式

举例:

Docstring InputRendered Outputdef example():    """    I{B{Inline markup} may be nested; and    it may span} multiple lines.      - I{Italicized text}      - B{Bold-faced text}      - C{Source code}      - M{Math}    Without the capital letter, matching    braces are not interpreted as markup:    C{my_dict={1:2, 3:4}}.    """

URLs

U{text<url>} 的形式创建网页链接:

def example():    """    - U{www.python.org}    - U{http://www.python.org}    - U{The epydoc homepage<http://epydoc.sourceforge.net>}    - U{The B{I{Python}} homepage<www.python.org>}    - U{Edward Loper<mailto:edloper@gradient.cis.upenn.edu>}    """

内部引用链接

L{text<object>} 的形式创建内部引用链接,引用的可以是Python对象:

def example():    """    - L{x_transform}    - L{search<re.search>}    - L{The I{x-transform} function <x_transform>}    """

索引

X{...} 的形式建立索引:

def example():    """    An X{index term} is a term that    should be included in the index.    """

特殊符号

S{code} 的形式嵌入特殊符号:

def example():    """    Symbols can be used in equations:      - S{sum}S{alpha}/x S{<=} S{beta}    S{<-} and S{larr} both give left    arrows.  Some other arrows are    S{rarr}, S{uarr}, and S{darr}.    """

转义特殊字符

有些字符是被 epytext 当作标记命令的,如果需要显示其本意,则进行转义:

def example():    """    This paragraph ends with two    colons, but does not introduce    a literal blockE{:}E{:}    E{-} This is not a list item.    Escapes can be used to write    unmatched curly braces:    E{rb}E{lb}    """

这里以 E{xxx} 的形式转义,其中 E{rb} 表示 }, 而 E{lb} 表示 { .

图片

G{graphtype args...} 的形式引入自动生成的图片,比如类派生关系图等:

Markup Description G{classtree classes…}显示类的等级图,没有提供类,则显示该docstring所在类本身的等级G{packagetree modules…}显示包的等级图,没有提供包,则显示该docstring所在包本身的等级G{impotgraph modules…}显示模块的等级图,没有提供模块,则显示该docstring所在模块本身的等级G{callgraph functions…}显示函数的等级图,没有提供函数,则显示该docstring所在函数本身的等级
2.5 epydoc的相关项目

参考: http://www.ast.cam.ac.uk/~rgm/dazle/software/dics/src/epydoc-3.0alpha2/doc/relatedprojects.html

主要有:

pydoceasydocdoc.pydoxygenjavadoc

2.6 完整举例

#!/usr/bin/env python## objdoc: epydoc command-line interface# Edward Loper## Created [03/15/02 10:31 PM]# $Id: gui.py 646 2004-03-19 19:01:37Z edloper $#"""Graphical interface to epydoc.  This interface might be useful forsystems where it's inconvenient to use the command-line interface(such as Windows).  It supports many (but not all) of the featuresthat are supported by the command-line interface.  It also supportsloading and saving of X{project files}, which store a set of relatedmodules, and the options that should be used to generate thedocumentation for those modules.Usage::    epydocgui [OPTIONS] [FILE.prj | MODULES...]    FILE.prj                  An epydoc GUI project file.    MODULES...                A list of Python modules to document.    -V, --version             Print the version of epydoc.    -h, -?, --help, --usage   Display this usage message    --debug                   Do not suppress error messages@todo: Use ini-style project files, rather than pickles (using thesame format as the CLI)."""__docformat__ = 'epytext en'#.....def document(options, cancel, done):    """    Create the documentation for C{modules}, using the options    specified by C{options}.  C{document} is designed to be started in    its own thread by L{EpydocGUI._go}.    @param options: The options to use for generating documentation.        This includes keyword options that can be given to        L{docwriter.html.HTMLWriter}, as well as the option C{target}, which        controls where the output is written to.    @type options: C{dictionary}    """#.....
3 doxygen

javadoc 类似,doxygen也是将文档嵌入代码中的,支持导出的文件格式:

HTMLCHMRTFPDFLaTeXman page等

使用doxygen生成文档的开源项目参考:

http://xerces.apache.org/xerces-c/apiDocs-3/classes.htmlC++ Sockets Library: http://www.alhem.net/Sockets/cocos2d: http://www.cocos2d-swift.org/

3.1 模板

/** * <A short one line description> * * <Longer description> * <May span multiple lines or paragraphs as needed> * * @param  Description of method's or function's input parameter * @param  ... * @return Description of the return value */

doxygen支持多种注释风格,这里 @param 表示参数, @return 表示返回值,遵循一定的格式即可。

3.2 样例

/** * @file * @author  John Doe <jdoe@example.com> * @version 1.0 * * @section LICENSE * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details at * http://www.gnu.org/copyleft/gpl.html * * @section DESCRIPTION * * The time class represents a moment of time. */class Time {    public:       /**        * Constructor that sets the time to a given value.        *        * @param timemillis Number of milliseconds        *        passed since Jan 1, 1970.        */       Time (int timemillis) {           // the code       }       /**        * Get the current time.        *        * @return A time object set to the current time.        */       static Time now () {           // the code       }};

良好的注释符,不但方便生成准确的文档,也使得简洁明了。

3.3 安装

从http://www.doxygen.org/download.html 下载相应平台源码,进行安装即可:

$ git clone https://github.com/doxygen/doxygen.git$ cd doxygen$ ./configure$ make$ make install$ doxygen --help
3.4 开始使用

3.4.1 第一步: 生成configure文件

$ doxygen -g [config_file_name]

也可以更新已有配置文件:

$ doxygen -u [config_file_name]
3.4.2 第二步: 指定使用的configure文件

直接使用已有配置文件:

$ doxygen  [config_file_name]
3.4.3 第三步: 为项目生成文档

在第二步就已经生成了文档,默认是HTML格式,一切根据配置文件来生成。

3.5 如何注释代码

为了和代码本身的注释有所区别,会在注释里面添加一些标志,但存在多种风格。

3.5.1 以2个星号开始(JAVADOC_AUTOBRIEF=YES)

/** * ... text ... */
3.5.2 以感叹号开始(Qt style, QT_AUTOBRIEF=YES)

/*! * ... text ... *///!//!... text ...//!////// ... text ...///
3.5.3 在变量后添加

int var; /*!< Detailed description after the member */int var; /**< Detailed description after the member */int var; //!< Detailed description after the memberint var; ///< Detailed description after the member

注意不能少了 < 符号.

3.5.4 一个较为完整的样例

/*! A test class */class Test{  public:    /** An enum type.      *  The documentation block cannot be put after the enum!      */    enum EnumType    {      int EVal1,     /**< enum value 1 */      int EVal2      /**< enum value 2 */    };    void member();   //!< a member function.  protected:    int value;       /*!< an integer value */};/////////////////////////////////////////////////////////** *  A test class. A more elaborate class description. */class Test{  public:    /**      * An enum.     * More detailed enum description.     */    enum TEnum {           TVal1, /**< enum value TVal1. */            TVal2, /**< enum value TVal2. */            TVal3  /**< enum value TVal3. */           }        *enumPtr, /**< enum pointer. Details. */       enumVar;  /**< enum variable. Details. */      /**       * A constructor.       * A more elaborate description of the constructor.       */      Test();      /**       * A destructor.       * A more elaborate description of the destructor.       */     ~Test();      /**       * a normal member taking two arguments and returning an integer value.       * @param a an integer argument.       * @param s a constant character pointer.       * @see Test()       * @see ~Test()       * @see testMeToo()       * @see publicVar()       * @return The test results       */       int testMe(int a,const char *s);      /**       * A pure virtual member.       * @see testMe()       * @param c1 the first argument.       * @param c2 the second argument.       */       virtual void testMeToo(char c1,char c2) = 0;      /**        * a public variable.       * Details.       */       int publicVar;      /**       * a function variable.       * Details.       */       int (*handler)(int a,int b);};
3.6 常用标签命令

标签 说明 @author作者@brief摘要@file文件说明 @version版本@todo改进内容 @var模块变量说明@typedef模块变量类型说明 @param参数说明@arg列表说明参数@return返回值@retval返回值类型 @note注解@attention注意@bug存在的问题@warning警告 @see参考信息
3.7 特殊标记命令

doxygen的文档很详细,支持的标记命令也很多: http://www.stack.nl/~dimitri/doxygen/manual/commands.html#cmdparam

4 后记

听了很多道理,依旧过不好这一生;学了很多文档标记,依旧写不好文档。

5 参考

http://en.wikipedia.org/wiki/Doxygenhttp://www.stack.nl/~dimitri/doxygen/index.htmlhttp://stackoverflow.com/questions/4126421/how-to-document-python-code-epydoc-doxygen-sphinxhttp://sphinx-doc.org/https://pypi.python.org/pypi/epydochttp://www.ast.cam.ac.uk/~rgm/dazle/software/dics/src/epydoc-3.0alpha2/doc/index.html


作者简介:

朱春来(Leslie Zhu),金融工程师,毕业于西安电子科技大学, 喜欢历史,喜欢编程. 日常在GNU/Linux环境下进行C/C++、Python开发,对Common Lisp、Node.js、金融等感兴趣。可以通过邮箱(pythonisland@gmail.com)联系他,或者直接在他的个人主页上留言.

访问朱春来(Leslie Zhu)的个人主页(http://lesliezhu.github.com)

代码注释与文档生成工具: epydoc与doxygen

相关文章:

你感兴趣的文章:

标签云: