正确使用注释

Proper use of comments

对于 Python 代码,PEP 257 提供了使用文档字符串记录结构实体的约定:包、模块、函数、类 和方法。

这几乎涵盖了所有内容。关于如何评论 Python 代码的 Stack Overflow 问题总是引出使用文档字符串的答案。

这个评论在哪? Pythonic 方法是否只使用文档字符串而不使用注释?或者他们有什么地方吗?

Python代码中注释的正确用法是什么?

Doc-strings = 给那些使用你函数的人的信息
inline-comments = 解释为什么代码是这样写的。

请参阅 requests library 以了解适当使用注释的项目示例。

何时使用 Doc-Strings

好的文档字符串提供的信息类型与您在通读 Python 文档时通常看到的信息类型相同。他们解释了函数的作用,描述了参数,如果有返回值,他们应该提及。文档字符串还应提及调用该函数可能发生的任何副作用。

考虑文档字符串的一种方法是考虑如果该功能显示在某些在线文档中您希望显示的信息。有像 Sphinx 这样的程序可以根据文档字符串自动生成文档。

何时使用评论

另一方面,评论解释了令人困惑的代码片段。他们的目的是帮助正在修复错误或以其他方式更改您的代码的人了解您的代码在做什么。应该使用它们来帮助解释仅通过查看就无法自我解释的代码行。

例子

以下面的洗牌算法为例。请注意,注释的重点是解释算法的工作原理,而不是每行代码的作用。我们知道如何阅读代码,但评论中的信息对任何查看代码的人都是有用的信息。另一方面,文档字符串提供了任何需要使用随机播放功能的人都想知道的所有信息。他们不关心算法的内部结构。他们关心 shuffle 函数的输入和输出。

def shuffle(artist_song_dict):
    """ Shuffles songs in a semi-random fashion while keeping songs by the same artist spread out, as described in
    https://labs.spotify.com/2014/02/28/how-to-shuffle-songs/
    artist_song_dict must be a dictionary where the keys equal the artist names and the values are an iterable of each artist's songs
    A list of shuffled songs is returned
    """
    lineup = {} #each song will be stored in this dictionary with a value between 0 and 1 representing the song's position in the lineup
    variation = .3
    for artist in artist_song_dict:
        songs = artist_song_dict[artist]
        random.shuffle(songs)

        # Distance between songs in the lineup, if we were to space the songs out evenly
        spread = 1/len(songs)

        # This is reffered to as the offset in the article, but I found this has a different purpose than what the article says.
        # Without this random variation, the number of songs an artists has in the lineup affects the probablity that their songs
        # will appear first (or sooner/later) in the lineup versus other artists
        artist_variation = random.uniform(0, spread-variation)

        for i, song in enumerate(songs):
            # We want to add some randomization to the lineup, but not too much, 
            # otherwise, songs by the same artists could be played twice.
            # The article recommends adding a 30% variation to each song
            song_variation = random.uniform(0, spread*variation)

            # Assign this song the next evenly spaced spot in the lineup plus our variations
            lineup[song] = i*(spread) + artist_variation + song_variation

    return sorted(lineup, key=lineup.get)



内联评论与块评论

内联评论看起来像这样

x = x + 1                 # Compensate for border

块评论看起来像这样

# Compensate for border.  These comments
# often cover multiple lines.
x = x + 1

两者都是有效的评论形式。我只是想指出有两种形式的意见。 PEP 8 特别 says 谨慎使用内联注释。我相信他们是在反对不恰当地使用注释来解释每一行代码是如何工作的。您经常在教程和 SO 上看到这一点,但在实践中,您不应该注释不言自明的代码。

Python PEP8 有一个评论部分。简而言之:

Use inline comments sparingly.

An inline comment is a comment on the same line as a statement. Inline comments should be separated by at least two spaces from the statement. They should start with a # and a single space.

Inline comments are unnecessary and in fact distracting if they state the obvious.

对于块注释:

Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a # and a single space (unless it is indented text inside the comment).

Paragraphs inside a block comment are separated by a line containing a single #.