Skip to content

PaddleRS代码注释规范

LutaoChu edited this page Mar 14, 2022 · 1 revision

PaddleRS代码注释规范

1 背景

代码注释是代码质量的重要体现,对于开源项目尤为重要。

2 目的

  1. 组内统一开发规范,编写高质量注释,便于用户和开发者阅读。
  2. 为新人提供指导。
  3. 为外部贡献者提供开发指南。

3 注释规范

借鉴Paddle文档规范,同时结合本repo的特点,制定如下规范:

注释由5个模块构成:

  • API功能描述
  • API参数
  • API返回值
  • API抛出异常
  • API示例代码

编写顺序从上到下。

3.1 API 功能描述

目标是让用户能快速看懂。可以拆解为3个部分,功能作用 + 计算公式 + 注解部分。

  • 功能作用:描述该API文档的功能作用;由于用户不一定有对应的背景,所以需要补充必要的细节
  • 计算公式(可选):如有需要,给出该API的计算公式。公式建议以Latex格式编写。
  • 注解部分(可选):加入API如有需要特殊说明的部分,可以在注解部分给出。

示例:

"""
    Add two tensors element-wise. The equation is: 

        out = x + y
        
    **Note**:
    ``paddle.add`` supports broadcasting. If you want know more about broadcasting, please refer to :ref:`user_guide_broadcasting` .
"""

3.2 API参数

要解释清楚每个参数的类型含义默认值(如果有)。

注意事项:

  • 可选参数要备注optional
  • 如果参数有多种类型,类型之间无需空格
  • 对于有默认值的参数,至少要讲清楚在默认值下的逻辑,而不仅仅是介绍这个参数是什么以及默认值是什么;

示例:

"""
    Args:
        x (Tensor): The input tensor, the data type should be float32, float64, int32, int64.
        components (function|class|list|tuple): Support 4 types of components.
        name (str, optional): Name for the operation (optional, default is None). 
"""

3.3 API返回值

先描述API 返回值的类型,然后描述API的返回值及其含义。

示例1:

"""
    Returns:
        (tuple). When label is None, it returns (im, im_info), otherwise it returns (im, im_info, label).
"""

示例2:

"""
    Returns:
        N-D Tensor. A location into which the result is stored. It’s dimension equals with x.
"""

示例3(Class返回值模板):

class xxx:
	"""
	...
    Returns:
        A callable object of xxx.
    """

3.4 API 抛出异常

使用范围:应在关键的场景下给出抛出异常的信息,普通场景尽可能给出,但不做强制要求。

示例:

"""
        Raises:
            ValueError: When `memory()` is called outside `block()` .
            TypeError: When init is set and is not a Variable.
"""

3.5 API 代码示例

对前文描述的API使用中的各种场景,尽可能的在一个示例中给出,并用注释给出对应的结果。

要求:用户复制示例代码到脚本即可运行。注意需要加必要的import。

使用范围:对用户开放的API便于开发者二次开发的基础API(如ComponentManager)都需要添加,其余API按需要添加。

Example示例:

    Examples:
    
            import paddle
            import numpy as np
            
            paddle.enable_imperative()
            np_x = np.array([2, 3, 4]).astype('float64')
            np_y = np.array([1, 5, 2]).astype('float64')
            x = paddle.imperative.to_variable(np_x)
            y = paddle.imperative.to_variable(np_y)
            
            z = paddle.add(x, y)
            np_z = z.numpy()
            # [3., 8., 6. ]
            
            z = paddle.add(x, y, alpha=10)
            np_z = z.numpy() 
            # [12., 53., 24. ]

多Example示例:

    Examples 1:

        from paddleseg.cvlibs.manager import ComponentManager

        model_manager = ComponentManager()

        class AlexNet: ...
        class ResNet: ...

        model_manager.add_component(AlexNet)
        model_manager.add_component(ResNet)

        # Or pass a sequence alliteratively:
        model_manager.add_component([AlexNet, ResNet])
        print(model_manager.components_dict)
        # {'AlexNet': <class '__main__.AlexNet'>, 'ResNet': <class '__main__.ResNet'>}

    Examples 2:

        # Or an easier way, using it as a Python decorator, while just add it above the class declaration.
        from paddleseg.cvlibs.manager import ComponentManager

        model_manager = ComponentManager()

        @model_manager.add_component
        class AlexNet: ...

        @model_manager.add_component
        class ResNet: ...

        print(model_manager.components_dict)
        # {'AlexNet': <class '__main__.AlexNet'>, 'ResNet': <class '__main__.ResNet'>}

3.6 语法

  • 措词准确。请使用深度学习领域通用的词汇和说法。
  • 语句通顺,符合英文语法。
  • 文档中的前后说明要一致,比如避免前面用label,后面用ground truth

3.7 其他注意事项

  • 以上各个模块间空一行,每个模块的内容需要缩进
  • 句首首字母大写
  • 代码示例的内容适当加空行,有层次感。且与标题Examples空一行
  • 除了公式等特殊情况,每句话结尾要有句号。

4 模板

4.1 空白模板

可用来copy到代码里,进行改写

    """
    xxx

    Args:

    Returns:

    Raises:
        xxError: 

    Examples:

        
    """

4.2 示例

class Activation(nn.Layer):
    """
    The wrapper of activations.

    Args:
        act (str, optional): The activation name in lowercase. It must be one of ['elu', 'gelu', 
            'hardshrink', 'tanh', 'hardtanh', 'prelu', 'relu', 'relu6', 'selu', 'leakyrelu', 'sigmoid', 
            'softmax', 'softplus', 'softshrink', 'softsign', 'tanhshrink', 'logsigmoid', 'logsoftmax', 
            'hsigmoid']. Default: None, means identical transformation.

    Returns:
        A callable object of Activation.

    Raises:
        KeyError: When parameter `act` is not in the optional range.

    Examples:

        from paddleseg.models.common.activation import Activation
        
        relu = Activation("relu")
        print(relu)
        # <class 'paddle.nn.layer.activation.ReLU'>

        sigmoid = Activation("sigmoid")
        print(sigmoid)
        # <class 'paddle.nn.layer.activation.Sigmoid'>

        not_exit_one = Activation("not_exit_one")
        # KeyError: "not_exit_one does not exist in the current dict_keys(['elu', 'gelu', 'hardshrink',
        # 'tanh', 'hardtanh', 'prelu', 'relu', 'relu6', 'selu', 'leakyrelu', 'sigmoid', 'softmax',
        # 'softplus', 'softshrink', 'softsign', 'tanhshrink', 'logsigmoid', 'logsoftmax', 'hsigmoid'])"
    """
    ...