Python Docstring 风格和写法学习

什么是Python Docstring

和Java类似,Python也通过注释形式的Docstring给程序、类、函数等建立文档。通过Docstring建立的文档不仅对人来说有更好的可读性,也能够让IDE等工具自动识别使用函数、类、变量等的一些限制,从而帮助我们更好地理解程序。

Python Docstring 的三种风格

总的来说,Python Docstring有三种主要风格,分别是reST风格、Google风格和Numpy风格:

reST风格

reST的全称是reStructredText。通过以冒号开头的几个关键字来说明类、函数中的参数、返回值、异常等。

例如我们要造一个双向链表的轮子,我们新建一个DoubleLinkList.py 文件。其中包含两个类,一个是双向链表的节点类DLLNode,一个是双向链表类DoubleLinkList

首先看一下DLLNode类。

class DLLNode(object):
    """
    The definition of node of double link list.

    :param val: The value of a node.
    :param prev: The pointer of the previous node of this node.
    :param next: The pointer of the next node of this node.
    :type val: Any
    :type prev: DLLNode, default None
    :type next: DLLNode, default None
    """

    def __init__(self, val, prev=None, next=None):
        self.val = val
        self.prev = prev
        self.next = next

我们可以看到在DLLNode类中通过三个双引号"""建立了对DLLNode类的docstring。注意docstring必须位于任意其他代码的开头。在类的docstring中,常见的有如下声明标记:

:param <类属性名称>: <描述>
:type <类属性名称>: <类型>

其中,类型除了基本类型,如intfloatstr等,还可以是列表类型List[type],元组类型Tuple[types],以及字典类型Dict[KeyType, ValueType]等,还可以是各种模块中定义的类型。注意当类型为列表、元组或字典时与Python本身自带类型的不同。

这里我们不需要再对DLLNode类中 __init__()函数添加docstring。在生成文档时,Python会自动将类的docstring复制给它的__init__()函数。

下面再看一下DoubleLinkList类。

class DoubleLinkList(object):
    """
    The definition of double link list.

    :param head: The head pointer of the list.
    :type head: DLLNode
    """
    def __init__(self, head):
        self.head = head

    def insert_node(self, val, node):
        """
        Insert a node before the node which data is val.

        :param val: The value to be find to insert a node before it.
        :param node: The node ready to insert.
        :type val: Any
        :type node: DLLNode
        """
        pass

    def remove_node(self, val):
        """
        Remove a node which data is val.

        :param val: The val of node to be removed.

        """
        pass

    def length(self):
        """
        Returns the length of this link table.

        :return: The length of this link table.
        :rtype: int
        """
        pass

    def search_node(self, val):
        """
        Search the first position of node which data equals val.

        :param val: The value to be searched.
        :return: The position of val first appeared.
        :rtype: int
        """
        pass

    def update_node(self, position, val):
        """
        Update the node in position by val.

        :param position: The position of the node to be updated.
        :param val: The target value of updated node.
        :type position: int
        :type val: Any
        """
        pass

假设我们给DoubleLinkList类设计了增删改查和求长度五个方法。我们可以看到,除了:param:type外,还有几个新的标签,列举如下:

:return: <对返回值的描述>
:rtype: <返回值类型>
:raises: <可能抛出的异常列表>

当我们在docstring中为函数指定了:param:type以后,如果在调用函数时给函数传入了错误的参数类型,IDE会发出warning,可以提醒我们传入正确的参数类型。

Google Style

除了reST风格,Google Style也是一种常见的docstring规范。

仍以上文的DoubleLinkList为例。Google Style的docstring如下:

class DLLNode(object):
    """
    The definition of node of double link list.

    Args:
        val (Any): The value of Node.
        prev (DLLNode): The previous node of this node.
        next (DLLNode): The next node of this node.


    """

    def __init__(self, val, prev=None, next=None):
        self.val = val
        self.prev = prev
        self.next = next


class DoubleLinkList(object):
    """
    The definition of double link list.

    Args:
        head (DLLNode): The head pointer of the link list.
    """
    def __init__(self, head):
        self.head = head

    def insert_node(self, val, node):
        """
        Insert a node before the node which data is val.

        Args:
            val (Any): The value to be find to insert a node before it.
            node (DLLNode): The node ready to insert.
        """
        pass

    def remove_node(self, val):
        """
        Remove a node which data is val.

        Args:
            val (DLLNode): The val of node to be removed.

        """
        pass

    def length(self):
        """
        Returns the length of this link table.

        Returns:
            int: The length of this link list.
        """
        pass

    def search_node(self, val):
        """
        Search the first position of node which data equals val.

        Args:
            val: The value to be searched.

        Returns:
            int: The first position of the searched value.
        """
        pass

    def update_node(self, position, val):
        """
        Update the node in position by val.

        Args:
            position (int): The position of node to be updated.
            val: The new value of target.
        """
        pass

与reST风格不同,Google Style将所有的参数写在Args标签下,而所有的返回值写在Returns标签下。我个人认为比起reST风格,Google Style的可读性要更好一些。在Args标签下,可以在参数名称后面加 (类型)来确定参数的类型,同样可以起到对参数类型的限制作用。

Numpy Style

Numpy是矩阵分析、科学计算、机器学习中都会用到的常见Python程序库。其文档详实完整,也是程序员们学习的典范之一。Numpy也有自己独特的Python Docstring风格。我们仍以DoubleLinkList模块为例来说明。

class DLLNode(object):
    """
    The definition of node of double link list.

    Parameters
    ----------
    val : Any
        The value of node.
    prev : DLLNode
        The previous node of this node.
    next : DLLNode
        The next node of this node.

    Attributes
    ----------
    val : Any
        The value of node.
    prev : DLLNode
        The previous node of this node.
    next : DLLNode
        The next node of this node.
    """

    def __init__(self, val, prev=None, next=None):
        self.val = val
        self.prev = prev
        self.next = next


class DoubleLinkList(object):
    """
    The definition of double link list.

    Parameters
    ----------
    head : DLLNode
        The head pointer of the link list.

    Attributes
    ----------
    head : DLLNode
        The head pointer of the link list.
    """
    def __init__(self, head):
        self.head = head

    def insert_node(self, val, node):
        """
        Insert a node before the node which data is val.

        Parameters
        ----------
        val:
            The value to be find to insert a node before it.
        node : DLLNode
            The node ready to insert.
        """
        pass

    def remove_node(self, val):
        """
        Remove a node which data is val.

        Parameters
        ----------
        val :
            The val of node to be removed.

        """
        pass

    def length(self):
        """
        Returns the length of this link table.

        Returns
        -------
        int
            The length of this link list.
        """
        pass

    def search_node(self, val):
        """
        Search the first position of node which data equals val.

        Parameters
        ----------
        val:
            The value to be searched.

        Returns
        -------
        int
            The first position of the searched value.
        """
        pass

    def update_node(self, position, val):
        """
        Update the node in position by val.

        Parameters
        ----------
        position :int
            The position of node to be updated.
        val:
            The new value of target.
        """
        pass

和Google Style不同,Numpy Style采用如下格式描述一个类:

"""
类描述

Parameters
----------
参数 : [类型]
    参数的描述
    
Attributes
----------
属性 : [类型]
    属性的描述
"""

其中Parameters和Attributes可以不一样。具体区别我也不是搞得很明白。

函数描述如下

"""
函数描述

Parameters
----------
参数 : [类型]
   参数的描述

Returns
-------
类型
    返回值的描述
    
Raises
------
异常名称
    异常描述

Examples
--------
范例描述

Yields(仅针对生成器函数)
------
类型
   生成器返回值描述
 
Note
----
注释内容
"""

Numpy风格的docstring似乎不能用sphinx来生成html形式的文档。

小结

本文介绍了Python程序设计中常见的三种docstring的风格,其中我个人认为Google Style相比之下是最好的一个,它既可以采用Sphinx来生成HTML格式的文档,也可以直接在命令行中通过help函数获得可读性更高的文档。但在Pycharm等IDE中,默认支持的是reST风格的。具体如何使用,就要看自己的喜好和项目要求了。

posted @ 2019-06-25 20:27  飞鸟_Asuka  阅读(10339)  评论(0编辑  收藏  举报