赞
踩
注释对于代码的阅读、扩展以及维护都非常重要。在 Python 中常用的注释方式有三种,分别为块注释( Block Comments )、行内注释( Inline Comments )、文档字符串( Documentation Strings )。首先我们需要了解的是在注释编写过程中的一些通用原则,这些原则不管针对哪种注释方式,都是值得参考的
应注重注释的可读性和完整性,这样有助于代码后续的扩展和维护;
应注重注释的实时性,即代码在修改或扩展过程中,及时更新对应的注释;
应优先使用英文编写注释
注释应为完整的句子;
当注释的开头不为以小写字母开始的标识符时,应大写首字母;
在包含多个句子的注释中,在非结尾句的结尾处可以使用两个空格等。
“#”号后空一格,段落间用空行分开(同样需要“#”号)
- # 块注释
- # 块注释
- #
- # 块注释
- # 块注释
块注释在代码内部比较常见,其通常由一至多个段落构成,段落之间应使用开头为 #
的空行隔开,每个段落由完整的句子构成,在每行以 #
和一个空格开始。另外,块注释和被注释代码之间应具有同级别的缩进,这样有助于区分注释和代码之间关联关系。
通常我们提到的这些细节和准则在 Python 标准库的编写中往往做的更好,我们以 Python 标准库 collections
中 Counter
对象的 fromkeys
方法的注释来进行示例说明,这段注释主要说明了在 Counter
类中没有定义 fromkeys
方法的原因
- @classmethod
- def fromkeys(cls, iterable, v=None):
- # There is no equivalent method for counters because the semantics
- # would be ambiguous in cases such as Counter.fromkeys('aaabbc', v=2).
- # Initializing counters to zero values isn't necessary because zero
- # is already the default value for counter lookups. Initializing
- # to one is easily accomplished with Counter(set(iterable)). For
- # more exotic cases, create a dictionary first using a dictionary
- # comprehension or dict.fromkeys().
- raise NotImplementedError(
- 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
-
'运行
行内注释是一种形式相对简单的注释,它和表达式或语句位于同一行,之间应通常使用两个空格隔开,注释部分应以 #
和一个空格开始。需要注意的一点是,在编写行内注释时,其描述要尽量明确,对于一些代码所表示的含义或逻辑显而易见时,行内注释没有必要再对其进行复述
- # 不提倡下面的方式, 是因为显而易见的
- my_list = [] # Make a list
-
- #至少使用两个空格和语句分开,注意不要使用无意义的注释
- # 正确的写法
- x = x + 1 # 边框加粗一个像素
-
- # 不推荐的写法(无意义的注释)
- x = x + 1 # x加1
在 Python 中,最重要的注释形式便是文档字符串( Documentation Strings ),我们也常称之为 “docstrings”,一方面用来对模块、类、函数、方法等进行说明;另一方面可以配合一些辅助工具来自动化生成代码文档(关于这部分,我们会在后面的小节中专门说明)。
我们现在或许还不能完全意识到文档字符串的重要性,但如果你了解开源软件的话,你一定会知道一个开源软件文档质量的好坏有时会决定它是否会流行起来。
对于文档字符串的形式来说,它通常是模块、类、方法、函数定义中的首个语句,使用类似 """docstrings"""
这样的形式。若在文档字符串中存在 \
,可使用 r"""docstrings"""
形式;若在文档字符串中使用 unicode,可使用 u"""docstrings"""
。对于所有模块、被另外的模块导入的类或函数、类中的公共方法(包括构造函数),均应编写文档字符串。对于包来说,也可在其 __init__.py
中编写文档字符串。
单行文档字符串结构较为简单,在单行文档字符串后不应有空行,避免对显而易见的含义进行复述。
- >>> def function_name():
- ... """docstrings"""
- ... pass
- ...
对于多行文档字符串来说,它的结构相对复杂,主要由引号、摘要行、空行、文档描述组成。整个文档字符串的缩进和代码首部缩进级别应相同,摘要行和首部引号可在同一行,也可在首部引号下一行,尾部引号单独成行。
对于普通类,其文档字符串可包含其实例属性、公共方法等的简要说明,在其文档字符串后可增加一个空行;对于继承于父类的子类,除了类的文档字符串中的内容外,可说明子类和父类的差异,比如对于重写父类的方法可使用 override 结合其他内容进行表示,对于调用父类方法并进行内容扩展的类方法,可使用 extend 结合其他内容进行表示;对于函数、方法,其文档字符串可包含参数、返回值说明、有可能抛出的异常以及功能等的简要说明;对于模块的文档字符串,可包含模块中可导入的类、函数等的简要说明;
对于包,其文档字符串可包含可导入的子包、模块等的简要说明(在 PEP 257 详细的描述了文档字符串的更多细节,感兴趣的同学可以查阅)。在这里我们分别以以 Python 标准库 os
中的一段文档字符串和第三方库 Tornado
中的一段文档字符串来进行示例说明
- # Tornado
- def import_object(name: str) -> Any:
- """Imports an object by name.
- ``import_object('x')`` is equivalent to ``import x``.
- ``import_object('x.y.z')`` is equivalent to ``from x.y import z``.
- >>> import tornado.escape
- >>> import_object('tornado.escape') is tornado.escape
- True
- >>> import_object('tornado.escape.utf8') is tornado.escape.utf8
- True
- >>> import_object('tornado') is tornado
- True
- >>> import_object('tornado.missing_module')
- Traceback (most recent call last):
- ...
- ImportError: No module named missing_module
- """
- if name.count(".") == 0:
- return __import__(name)
-
- parts = name.split(".")
- obj = __import__(".".join(parts[:-1]), fromlist=[parts[-1]])
- try:
- return getattr(obj, parts[-1])
- except AttributeError:
- raise ImportError("No module named %s" % parts[-1])
在 PyCharm 中我们很方便的编写函数或方法的文档字符串,比如我们编写了这种形式的函数后:
- def function_name(var_one, var_two: bool = False):
- """"""
- pass
'运行
只需要在引号中间回车,PyCharm 会帮助我们生成一个标准的结构
- def function_name(var_one, var_two: bool = False):
- """
-
- :param var_one:
- :param var_two:
- :return:
- """
- pass
'运行
文档字符串可通过对象的 __doc__
属性查看,同时也可借助 Python 的内置函数 help()
来查看。同时,编写良好的文档字符串还可以结合自动化工具帮助我们生成代码文档,比如 Python 自带的 pydoc
命令,上面提到的第三方工具 sphinx
等
- >>> def function_name():
- ... """docstrings"""
- ... pass
- ...
- >>> function_name.__doc__
- 'docstrings'
- >>> help(function_name)
- Help on function function_name in module __main__:
-
- function_name()
- docstrings
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。