Python文件的通用头格式是什么?

630

我在一份关于Python编码指南的文档中看到了以下Python源文件的标题格式:

#!/usr/bin/env python

"""Foobar.py: Description of what foobar does."""

__author__      = "Barack Obama"
__copyright__   = "Copyright 2009, Planet Earth"

这是Python世界中的标准头格式吗? 在头部还能放置哪些字段/信息呢? Python专家们,请分享一下有关良好Python源代码头的准则 :-)


这里是一个很好的起点:PEP 257,它讲解了文档字符串,并链接到其他几个相关文档。 - Peter
哈哈,太棒了@JonathanHartley!对于我的项目,就像你所说的“我沉迷于我的强迫症癖好。” 哈哈哈 https://dev59.com/xmQo5IYBdhLWcg3wOtMC#51914806 - JayRizzo
2
强迫症(OCD) - Timo
5个回答

686

这些都是Foobar模块的元数据。

第一个元数据是该模块的docstring,其已经在Peter's answer中进行了解释。

如何组织我的模块(源文件)? (存档)

每个文件的第一行应该是 #!/usr/bin/env python 这样可以将该文件作为脚本隐式地调用解释器,例如在 CGI 上下文中运行。

接下来应该是具有描述的docstring。 如果描述很长,则第一行应该是一个独立的简短摘要,通过换行符与其余部分分开。

包括导入语句在内的所有代码都应跟随在docstring之后。 否则,解释器将不会识别该docstring,并且您将无法在交互会话中访问它(即通过obj.__doc__),也无法使用自动化工具生成文档。

首先导入内置模块,其次是第三方模块,然后是路径的任何更改以及您自己的模块。 特别是,路径的添加和模块名称可能会快速更改:将它们放在一个地方可以更容易地找到。

接下来应该是作者信息。 此信息应遵循以下格式:

__author__ = "Rob Knight, Gavin Huttley, and Peter Maxwell"
__copyright__ = "Copyright 2007, The Cogent Project"
__credits__ = ["Rob Knight", "Peter Maxwell", "Gavin Huttley",
                    "Matthew Wakefield"]
__license__ = "GPL"
__version__ = "1.0.1"
__maintainer__ = "Rob Knight"
__email__ = "rob@spot.colorado.edu"
__status__ = "Production"

状态通常应该是“原型”,“开发”或“生产”中的一个。 __maintainer__ 应该是导入后将修复错误和进行改进的人。 __credits____author__ 不同,它包括报告 bug 修复,提出建议等但实际上没有编写代码的人。

这里有更多信息,列出了被认可的元数据,如__author____authors____contact____copyright____license____deprecated____date____version__


8
新文件的标题信息是否可以自动化创建? - Hauke
235
我认为在导入之后放置所有这些元数据是个不好的主意。那些适用于单个文件(例如作者、日期)的元数据已经被源代码管理系统所跟踪。在文件本身中再加入一个错误和过时的副本似乎是不正确的。而适用于整个项目(例如许可证、版本控制)的部分,似乎更适合位于项目级别,在自己的文件中,而不是在每个源代码文件中。 - Jonathan Hartley
37
完全同意Jonathan Hartley的看法。下一个接手这段代码的人有三个选择:
  1. 每次编辑代码时都完全更新元数据
  2. 不管它,这样会导致不准确
  3. 全部删除。
选择1是浪费时间,特别是因为他们绝对没有信心在收到元数据时其是否已经更新。选项2和3意味着你在一开始放置它的时间被浪费了。解决方案:节省每个人的时间,不要放置元数据。
- spookylukey
93
大多数 Python 文件都不需要有 shebang 行。 - Mike Graham
18
根据PEP 8规范,__version__需要直接放在主文档字符串之后,并且前后需要有一个空行。同时,最佳实践是在shebang下面立即定义字符集 - # -*- coding: utf-8 -*- - Dave Lasley
显示剩余10条评论

219

我强烈支持使用最小的文件头,也就是仅包含:

#!/usr/bin/env python # [1]
"""\
This script foos the given bars [2]

Usage: myscript.py BAR1 BAR2
"""
import os   # standard library, [3]
import sys

import requests  # 3rd party packages

import mypackage  # local source
  • [1] 哈希注释只有在文件需要被直接执行,即以 myscript.pymyscript 或甚至 python myscript.py 运行时才需要添加。在最后一种情况下不使用哈希注释,但提供它可以给用户选择以任何一种方式执行它。如果该文件是一个模块,仅用于被其他Python文件导入,则不应包含哈希注释。
  • [2] 模块文档字符串。
  • [3] 导入语句按照标准的方式分组,即三组导入语句之间各有一个空行。每个组内部,导入语句应按字母顺序排序。最终一组,导入自本地源,可以是如上所示的绝对导入,也可以是显式相对导入。

其他内容都是浪费时间-对作者和后续维护者都是如此。它浪费了文件顶部宝贵的可视空间,其中的信息最好在其他地方进行跟踪,并且容易变得过时并且具有误导性。

如果您有法律声明或许可信息,它应该放在单独的文件中。它不需要感染每个源代码文件。您的版权应该是其中一部分。人们应该能够在您的 LICENSE 文件中找到它,而不是在随机的源代码中。

作者和日期等元数据已经由您的源代码控制进行维护。没有必要在文件本身中添加较少详细、错误和过时版本的相同信息。

我认为没有其他数据是每个人都需要放入所有源文件的。您可能有某些特定的要求,但这些东西仅适用于您,按定义只适用于您。它们在“推荐给所有人的通用标题”中没有任何位置。


29
完全同意-在多个地方复制代码是一种罪恶,因此为什么在标题信息上也要这样做。将其放在一个单独的位置(项目根目录),避免在许多文件中维护此类信息带来的麻烦。 - Graeme
15
虽然我同意源代码控制通常提供更准确的作者信息,但有时候作者只发布源代码而没有提供访问存储库的权限,或者可能是分发方式的限制,例如:从pypi进行集中安装。因此,在模块头中嵌入作者信息仍然是有益的。 - pram
6
嘿Pram。我无法想象出一个实际有用的使用案例。我可以想象有人想要了解整个项目的作者信息,并从一个单一的中心位置,比如项目的README或文档中获取主要贡献者列表的价值。但是,谁会(a)想知道每个文件的作者信息,(b)没有访问源代码库的权限,(c)不在乎信息是否不正确或过时呢? - Jonathan Hartley
16
许多许可证要求您在每个文件中包含许可证样板,原因非常充分。如果有人拿走一两个文件并重新分发它们而没有附上许可证,接收者就不知道使用的是什么许可证,他们必须追溯下去才行(假设他们是出于诚意)。 - alexia
5
许多模块(如scipy、numpy、matplotlib)都有“__version__”元数据,我认为这很好,因为它应该对程序和在交互式解释器中快速检查是可访问的。然而,作者和法律信息应该放在另一个文件中。除非您有使用“if 'Rob' in __author__:”的情况。 - endolith
显示剩余9条评论

51

上面的回答非常详细,但如果您想快速复制粘贴一个简单的标题,可以使用以下内容:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Module documentation goes here
   and here
   and ...
"""

为什么这是一个好的选择:

  • 第一行是给*nix用户用的。它将选择用户路径下的Python解释器,因此将自动选择用户首选解释器。
  • 第二个是文件编码。现在每个文件都必须有一个关联的编码。UTF-8将在任何地方都可以使用。只有旧项目才会使用其他编码。
  • 非常简单的文档。它可以填充多行。

另请参阅:https://www.python.org/dev/peps/pep-0263/

如果您只在每个文件中编写一个类,则甚至不需要文档(它将放在类doc内)。


13
现今每个文件都必须有一个相关的编码。这种说法似乎有误导性。UTF-8 是默认编码,因此不指定编码也完全没有问题。 - Jonathan Hartley
1
@JonathanHartley 在 Python 2 中它不是默认的。我喜欢加上它,因为“显式优于隐式”。 - neves
6
如果使用Python 2,我同意这个说法有道理。对于Python3,就我个人而言,当默认值合理且普遍适用时,我愿意依赖隐式方式。每次使用加号"+"时,我们不需要明确定义其含义。 - Jonathan Hartley

25

如果您使用非ASCII字符集,请参阅PEP 263

摘要

本PEP提议引入一种语法来声明Python源文件的编码方式。然后,Python解析器将使用给定的编码方式来解释该文件的内容。最重要的是,这增强了源代码中Unicode文字的解释,并使得可以直接在支持Unicode的编辑器中使用UTF-8等编码方式编写Unicode文字。

问题

在Python 2.1中,只能使用基于Latin-1的编码“unicode-escape”来编写Unicode文字。这使得编程环境对于许多亚洲国家的Python用户而言不太友好。程序员可以使用喜欢的编码方式编写其8位字符串,但必须使用“unicode-escape”编码方式编写Unicode文字。

解决方案建议

我建议通过在文件顶部使用特殊注释来为每个Python源文件定义编码方式,从而使Python源代码编码方式可见且可更改。

为了使Python能够感知这种编码声明,必须对处理Python源代码数据进行一些概念性的更改。

定义编码方式

如果没有给出其他编码提示,Python将默认使用ASCII作为标准编码。

要定义源代码编码方式,必须在源文件中放置一个特殊的注释,该注释应作为文件的第一行或第二行,例如:

      # coding=<encoding name>

或(使用流行编辑器所识别的格式)

      #!/usr/bin/python
      # -*- coding: <encoding name> -*-
或。
      #!/usr/bin/python
      # vim: set fileencoding=<encoding name> :

...


23
值得注意的是,自Python 3以来,默认字符集为UTF-8。 - alexia

9

在一些项目中,我在Linux机器的第一行使用以下代码:

# -*- coding: utf-8 -*-

作为文档和作者的信用,我喜欢在多行中使用简单的字符串。这是一个来自Example Google Style Python Docstrings的例子。
# -*- coding: utf-8 -*-
"""Example Google style docstrings.

This module demonstrates documentation as specified by the `Google Python
Style Guide`_. Docstrings may extend over multiple lines. Sections are created
with a section header and a colon followed by a block of indented text.

Example:
    Examples can be given using either the ``Example`` or ``Examples``
    sections. Sections support any reStructuredText formatting, including
    literal blocks::

        $ python example_google.py

Section breaks are created by resuming unindented text. Section breaks
are also implicitly created anytime a new section starts.

Attributes:
    module_level_variable1 (int): Module level variables may be documented in
        either the ``Attributes`` section of the module docstring, or in an
        inline docstring immediately following the variable.

        Either form is acceptable, but the two should not be mixed. Choose
        one convention to document module level variables and be consistent
        with it.

Todo:
    * For module TODOs
    * You have to also use ``sphinx.ext.todo`` extension

.. _Google Python Style Guide:
   http://google.github.io/styleguide/pyguide.html

"""

还可以添加以下内容:

        """
        @Author: ...
        @Date: ....
        @Credit: ...
        @Links: ...
        """

其他格式

  • Meta-information markup | devguide

    """

          :mod:`parrot` -- Dead parrot access
          ===================================
    
          .. module:: parrot
             :platform: Unix, Windows
             :synopsis: Analyze and reanimate dead parrots.
          .. moduleauthor:: Eric Cleese <eric@python.invalid>
          .. moduleauthor:: John Idle <john@python.invalid>
      """
    
  • /common-header-python

          #!/usr/bin/env python3  Line 1
          # -*- coding: utf-8 -*- Line 2
          #----------------------------------------------------------------------------
          # Created By  : name_of_the_creator   Line 3
          # Created Date: date/month/time ..etc
          # version ='1.0'
          # ---------------------------------------------------------------------------
    

同其他答案一样,我也做出了相似的报告

__author__ = "Rob Knight, Gavin Huttley, and Peter Maxwell"
__copyright__ = "Copyright 2007, The Cogent Project"
__credits__ = ["Rob Knight", "Peter Maxwell", "Gavin Huttley",
                    "Matthew Wakefield"]
__license__ = "GPL"
__version__ = "1.0.1"
__maintainer__ = "Rob Knight"
__email__ = "rob@spot.colorado.edu"
__status__ = "Production"

1
自从Python3以后,无需定义utf-8编码,因为它是默认的。顺便说一下,这与Linux无关。 - Mikaelblomkvistsson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接