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風格的。具體如何使用,就要看自己的喜好和項目要求了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章