在非标准上下文中使用三引号创建“文档字符串”是一种好习惯吗?

时间:2018-11-06 21:11:42

标签: python comments pep8 docstring

我正在查看某人的代码,这些代码到处都是这种“文档字符串”:

SLEEP_TIME_ON_FAILURE = 5
"""Time to keep the connection open in case of failure."""

SOCKET_TIMEOUT = 15
"""Socket timeout for inherited socket."""

...

根据Python文档,文档字符串仅适用于模块,类或方法开头的上下文。

上述非标准做法的含义是什么?为什么Python允许这样做?这对性能没有影响吗?

3 个答案:

答案 0 :(得分:3)

在python中,"""是多行字符串的语法。

s1 = """This is a multi-line string."""
s2 = """This is also a multi-line
string that stretches 
across multiple lines"""

如果这些字符串未存储到变量中,则将立即对其进行垃圾回收,并从本质上将其忽略,但它们仍会占用一些开销。另一方面,解释器实际上完全忽略了使用#的注释。

该规则的唯一例外是,此文档字符串紧接在函数或类定义之后或在模块之上。在这种情况下,它存储在特殊变量__doc__中。

根据PEP8

  

文档字符串   在PEP 257中,编写好的文档字符串(也称为“文档字符串”)的约定不朽。

     

为所有公共模块,函数,类和方法编写文档字符串。对于非公共方法,文档字符串不是必需的,但是您应该使用注释来描述该方法的作用。此注释应出现在def行之后。

答案 1 :(得分:3)

就Python而言,这些不是文档字符串。它们只是用作表达式语句的字符串文字。您可以这样做-您可以将任何有效的Python表达式用作其自己的语句。 Python不在乎表达式是否实际执行任何操作。对于单独一行的字符串,唯一的性能影响是在字节码编译时需要进行很少的额外工作。因为这些字符串已经优化,所以在运行时没有影响。

某些文档生成器确实会查看这些字符串。例如,非常常见的Sphinx autodoc扩展名将解析这些字符串以记录直接位于它们之上的所有内容。在更改代码之前,请检查是否正在使用类似的东西。

答案 2 :(得分:1)

在这种情况下,您应该使用内嵌注释,PEP8样式指南会明确定义https://www.python.org/dev/peps/pep-0008/#comments,例如:

Py4JError                                 Traceback (most recent call `last)`
<ipython-input-5-313e7d9fd8ee> in <module>()
  1 from pyspark import SparkContext, SparkConf
  2 conf = SparkConf().setMaster("local").setAppName("Reference")
--> 3 sc = SparkContext(conf = conf)
  4 #ref = sc.textFile("reference.csv").map(lambda line: line.split(","))
  5 #ref_res = ref.saveAsTextFile("ref.txt")

~/anaconda3/lib/python3.6/site-packages/pyspark/context.py in __init__(self, master, appName, sparkHome, pyFiles, environment, batchSize, serializer, conf, gateway, jsc, profiler_cls)
    116         try:
    117             self._do_init(master, appName, sparkHome, pyFiles, environment, batchSize, serializer,
--> 118                           conf, jsc, profiler_cls)
    119         except:
    120             # If an error occurs, clean up in order to allow future SparkContext creation:

~/anaconda3/lib/python3.6/site-packages/pyspark/context.py in _do_init(self, master, appName, sparkHome, pyFiles, environment, batchSize, serializer, conf, jsc, profiler_cls)
    193         # data via a socket.
    194         # scala's mangled names w/ $ in them require special treatment.
--> 195         self._encryption_enabled = self._jvm.PythonUtils.getEncryptionEnabled(self._jsc)
    196 
    197         self.pythonExec = os.environ.get("PYSPARK_PYTHON", 'python')

~/anaconda3/lib/python3.6/site-packages/py4j/java_gateway.py in __getattr__(self, name)
   1514         else:
   1515             raise Py4JError(
-> 1516                 "{0}.{1} does not exist in the JVM".format(self._fqn, name))
   1517 
   1518     def _get_args(self, args):

Py4JError: org.apache.spark.api.python.PythonUtils.getEncryptionEnabled does not exist in the JVM