【问题标题】:Should you always document functions, even if redundant (specifically python)?您是否应该始终记录函数,即使是多余的(特别是 python)?
【发布时间】:2015-10-08 15:24:40
【问题描述】:

我尝试使用具有活动性和描述性的函数名称,然后使用活动和描述性文本 (!) 对其进行记录。这会生成看起来冗余的代码。

python 中的简化(但不是那么不切实际)示例,遵循 numpy docstring 样式:

def calculate_inverse(matrix):
    """Calculate the inverse of a matrix.

    Parameters
    ----------
    matrix : ndarray
        The matrix to be inverted.

    Returns
    -------
    matrix_inv : ndarray
        The inverse of the matrix.

    """
    matrix_inv = scipy.linalg.inv(matrix)
    return matrix_inv

特别是对于 python,我已经阅读了 PEP-257 和 sphinx/napoleon 示例 numpy 和 Google 样式的文档字符串。我喜欢我可以为我的函数自动生成文档,但是对于像上面这样的冗余示例,“最佳实践”是什么?不应该简单地记录“明显”的类、函数等吗? “显而易见”的程度当然会变得主观......

我想到的是开源的分布式代码。多位作者建议代码本身应该是可读的(calculate_inverse(A)dgetri(A) 更好),但多个最终用户将从 sphinx 样式的文档中受益。

【问题讨论】:

  • 如果你只是委托给另一个函数,你可以使用例如calculate_inverse.__doc__ = scipy.linalg.inv.__doc__ 给它相同的文档。但是,您 为谁编写此文档?
  • 请注意,复制__doc__ 适用于导入代码的sphinx 等工具。它可能不适用于像 epydoc 这样的工具,它只是从文本中解析文档字符串。
  • @jonrsharpe - 也许这个例子过于简化了;我的意思不仅仅是调用其他函数的函数。我只是指任何完全按照其名称所说的代码。
  • @barford 请注意,一个人的Ronseal 是另一个人的混淆。该名称也不一定告诉您该函数接受什么、它返回什么和/或可能引发什么等,以及如果您提供最终用户文档(如格式所暗示的那样),则代码是自记录的不一定有益。
  • @ali_m - 之前已经彻底解决了这个问题。请参阅herehereherehere。值得注意的是,其中两个已作为重复项关闭,值得关注问题链以查看其他答案。

标签: python-sphinx docstring numpydoc sphinx-napoleon


【解决方案1】:

我一直遵循代码告诉你它做了什么的指导方针,添加了cmets来解释为什么它做某事.

如果你看不懂代码,你就没有生意看它,所以有(极端):

index += 1   # move to next item

完全是浪费时间。对名为calculate_inverse(matrix) 的函数的评论也是如此,该函数声明它计算矩阵的逆矩阵。

而类似:

# Use Pythagoras theorem to find hypotenuse length.
hypo = sqrt (side1 * side1 + side2 * side2)

可能更合适,因为它添加了有关方程式来源的信息,以防您需要进一步调查。

真正应该为添加信息保留注释,例如用于计算逆的算法。在这种情况下,由于您的算法只是将工作交给scipy,因此完全没有必要。

如果您必须在此处有一个用于自动生成文档的文档字符串,那么对于这个非常简单的案例,我当然不会超越单行变体:

"""Return the inverse of a matrix"""

【讨论】:

  • 虽然我同意 cmets 的这一点(PEP-8 也是如此),但文档字符串的情况不太清楚。
  • @barford -- 我认为重点是为什么?您是否需要自动生成文档的文档字符串(例如通过 sphinx?)。还是只是为了你未来的自己阅读代码?如果是后者,并且文档字符串只告诉您快速浏览一下代码就会告诉您,那么它可能不值得。如果是前者,那么您需要开始平衡用户阅读文档不会看到代码和增加的维护成本这一事实。
  • @mgilson 所说的,这完全是关于你为谁写的。如果您使用的 IDE 也可以使用它们(例如 PyCharm),那也可能是相关的。
【解决方案2】:

“总是”?绝对不是。尽量少评论。评论撒谎。他们总是撒谎,如果他们不撒谎,那么他们明天就会撒谎。这同样适用于许多文档。

您应该为您的代码编写 cmets/文档的唯一时间 (imo) 是当您向客户/客户提供库时,或者您处于开源项目中时。在这些情况下,您还应该有一个严格的标准,这样就不会有任何歧义,应该和不应该记录什么,以及如何记录。

在这些情况下,您还需要建立关于谁负责更新文档的工作流程,因为他们将始终与代码不同步。

因此,总而言之,如果您能提供帮助,请永远不要评论/记录。如果你必须(因为发布库/做开源),请正确执行(tm)。

【讨论】:

    【解决方案3】:

    清晰、简洁、写得很好且位置正确的 cmets 通常很有用。但是,在您的示例中,我认为代码在没有 cmets 的情况下是独立的。它可以双向进行。评论范围从需要和优秀到完全无用。

    这是一个重要的话题。您应该阅读 Robert Martin 等人 (2008) 的“Clean Code: A Handbook of Agile Software Craftsmanship”中关于 cmets 的章节。第 4 章“注释”以这样的断言开头,“使用少量 cmets 的清晰而富有表现力的代码远优于使用大量 cmets 的杂乱和复杂的代码。与其把时间花在写解释你造成的烂摊子的 cmets 上,不如把它花在清理烂摊子上。”本章继续对 cme​​ts 进行了精彩的讨论。

    【讨论】:

    • 为优秀书籍的链接点赞。
    【解决方案4】:

    是的,您应该始终记录函数。

    许多答案都写了评论你的代码,这是非常不同的。我说的是文档字符串,它 document 你的界面。

    文档字符串很有用,因为您可以在 python 解释器中获得交互式帮助。例如,

    import math
    help(math)
    

    向您显示以下帮助:

        ...
        cos(...)
            cos(x)
    
            Return the cosine of x (measured in radians).
    
        cosh(...)
            cosh(x)
    
            Return the hyperbolic cosine of x.
        ...
    

    请注意,尽管 coscosh 非常熟悉(并且完全重复了 C math.h 中的函数),但它们仍被记录在案。对于 cos,它明确声明它的参数应该是弧度。对于您的示例,了解 matrix 可能是什么会很有用。它是一个数组数组吗?一个元组的元组,或者一个 ndarray,正如您在其正确的文档中正确写的那样?矩形矩阵或零矩阵适合吗?

    另一个“熟悉”的函数是 os 中的 chdir,它的文档如下:

        chdir(...)
            chdir(path)
    
            Change the current working directory to the specified path.
    

    坦率地说,并不是标准库模块中的所有函数都被记录在案。我在 os 中发现了一个类 statvfs_result 的未记录方法:

         |  __reduce__(...)
    

    也许它仍然是您应该记录的一个很好的例子。我承认我忘记了 reduce 是做什么的,所以我不知道这个方法。更熟悉的 __eq____ne__ 仍然记录在该类中(如 x.__eq__(y) <==> x==y)。

    如果你不记录你的函数,你的模块的帮助将如下所示:

        calculate_inverse(matrix)
    

    函数会更多地聚集在一起,因为文档字符串占用了额外的垂直空间。

    为看不到您的代码的人编写一个文档字符串。如果函数真的很简单,那么文档字符串也应该很简单。它将让人相信该函数确实很简单,并且不会从该未记录的函数中引发任何意外(如果他们不费心编写文档,他们是否有能力和负责编写好的代码,真的吗?)

    PEP 和其他准则的精神是代码应该对所有人都有益。 我很确定有人会遇到困难,这对你来说是显而易见的。 我(目前)用我的笔记本电脑写东西,屏幕不是很大,在 vim 中只有一个窗口,但我按照 PEP 8 写,says:“限制所需的编辑器窗口width 使得并排打开多个文件成为可能,并且在使用在相邻列中显示两个版本的代码审查工具时效果很好”。 PEP 257 recommends docstrings 可以很好地与 Emacs 的填充段落配合使用。

    所以,我不知道什么时候不写文档字符串是值得的。但是,由于 PEP 和指南只是建议,如果您的函数不会被很多人使用,如果您将来不会使用它,并且如果您不想编写好的代码(在最少)。

    【讨论】:

    • P.S.对于您的特定示例,我会将文档字符串设为单行,而不是您所写的。 """"计算一个矩阵的逆矩阵(ndarray)。""" - 如果你不添加关于非退化矩阵,“参数”膨胀字符串似乎太过分了。
    猜你喜欢
    • 2012-01-16
    • 2011-03-16
    • 2016-02-16
    • 1970-01-01
    • 2011-11-11
    • 2021-05-16
    • 2021-10-03
    • 1970-01-01
    相关资源
    最近更新 更多