Каков общий формат заголовка файлов Python?

508

Я встретил следующий формат заголовка для исходных файлов 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 , в котором говорится о Docstrings и ссылки на несколько других соответствующих документов.
Питер
41
Возможно, полезное руководство для тех, кто читает разные ответы на этот вопрос, - подумать, для каких целей они ожидают использовать эти заголовки файлов. Если у вас есть конкретный вариант использования (например, мой адвокат говорит, что судебные дела проиграны, потому что разработчики не смогли разместить информацию об авторских правах в каждом отдельном файле), добавьте и сохраните информацию, необходимую для этого варианта использования. В противном случае, вы просто потворствуете своему фетишу ОКР.
Джонатан Хартли
хаха здорово @JonathanHartley! Для моих собственных проектов, как вы говорите: «Я балую свой ОКР фетиш». хахааха stackoverflow.com/a/51914806/1896134
JayRizzo

Ответы:

577

Это все метаданные для Foobarмодуля.

Первый - это docstringмодуль, который уже объяснен в ответе Петра .

Как мне организовать свои модули (исходные файлы)? (Архив)

Первая строка каждого файла должна быть #!/usr/bin/env python. Это позволяет запускать файл как скрипт, неявно вызывающий интерпретатор, например, в контексте CGI.

Далее должна быть строка документации с описанием. Если описание длинное, первая строка должна быть краткой, которая имеет смысл сама по себе, отделенная от остальных новой строкой.

Весь код, включая операторы импорта, должен следовать за строкой документации. В противном случае строка документации не будет распознаваться интерпретатором, и вы не сможете получить к ней доступ в интерактивных сеансах (т. Е. Через 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__что __credits__включает людей, которые сообщили об исправлениях ошибок, внесли предложения и т. д., но на самом деле не написали код.

Здесь у вас есть дополнительная информация, распечатка __author__, __authors__, __contact__, __copyright__, __license__, __deprecated__, __date__и __version__признанные метаданные.

Эстебан Кюбер
источник
7
Может ли создание информации заголовка как-то быть автоматизировано для новых файлов?
Хауке
184
Я думаю, что все эти метаданные после импорта - плохая идея. Части этих метаданных, которые применяются к одному файлу (например, автор, дата), уже отслеживаются системой контроля версий. Размещение ошибочной и устаревшей копии той же самой информации в самом файле кажется мне неправильным. Части, которые применяются ко всему проекту (например, лицензия, управление версиями), кажутся лучше расположенными на уровне проекта, в собственном файле, а не в каждом файле исходного кода.
Джонатан Хартли
28
Полностью согласен с Джонатаном Хартли. У следующего человека, унаследовавшего код, есть три варианта: 1) обновлять его каждый раз, когда он / она редактирует код 2) оставлять его в покое, в этом случае он будет неточным 3) удалять все. Вариант 1 - пустая трата времени, тем более что они абсолютно не уверены в том, что метаданные были обновлены, когда они его получили. Варианты 2 и 3 означают, что ваше время, потраченное на это, было потрачено впустую. Решение: сэкономить всем время и не ставить его там.
spookylukey
77
У большинства файлов Python нет причин иметь строчку шебанга.
Майк Грэм,
15
Согласно PEP 8, __version__должен быть непосредственно после основной строки документации, с пустой строкой до и после. Кроме того, лучше всего определять свою кодировку сразу под шебангом -# -*- coding: utf-8 -*-
Дэйв Лэсли
179

Я решительно поддерживаю минимальные заголовки файлов, под которыми я подразумеваю просто:

  • Hashbang ( #!строка), если это исполняемый скрипт
  • Модуль документации
  • Импорт, сгруппированный стандартным способом, например:
  import os    # standard library
  import sys

  import requests  # 3rd party packages

  import mypackage.mymodule  # local source
  import mypackage.myothermodule  

то есть. три группы импорта, с одной пустой строкой между ними. Внутри каждой группы импорт сортируется. Последняя группа, импорт из локального источника, может быть либо абсолютным импортом, как показано, либо явным относительным импортом.

Все остальное - пустая трата времени, визуального пространства и активно вводит в заблуждение.

Если у вас есть правовая оговорка или информация о лицензировании, она помещается в отдельный файл. Не нужно заражать каждый файл исходного кода. Ваше авторское право должно быть частью этого. Люди должны иметь возможность найти его в вашем LICENSEфайле, а не в произвольном исходном коде.

Метаданные, такие как авторство и даты, уже поддерживаются вашим источником контроля. Нет необходимости добавлять менее детальную, ошибочную и устаревшую версию той же информации в сам файл.

Я не верю, что есть какие-то другие данные, которые каждый должен поместить во все свои исходные файлы. У вас может быть какое-то конкретное требование сделать это, но такие вещи по определению применимы только к вам. Им не место в «общих заголовках, рекомендуемых для всех».

Джонатан Хартли
источник
23
Не могу согласиться больше - грех повторять код в нескольких местах, так зачем делать то же самое для информации заголовка. Поместите его в одном месте (корневой каталог проекта) и избегайте хлопот, связанных с хранением такой информации во многих файлах.
Грэм
13
Хотя я согласен с тем, что контроль версий имеет тенденцию предоставлять более достоверную информацию об авторах, иногда авторы распространяют источник только без предоставления доступа к репозиторию, или, возможно, именно так работает распределение, например: централизованная установка из pypi. Таким образом, встраивание информации об авторстве в заголовок модуля все еще полезно.
детская
6
Привет, коляска. У меня возникли проблемы при рассмотрении варианта использования, где это действительно полезно. Я могу представить, что кто-то хочет узнать информацию об авторстве для проекта в целом, и он может получить ценность из списка основных участников в одном центральном месте, например, README или документации проекта. Но кто (а) хотел бы знать авторство отдельных файлов , и (б) не имел бы доступа к исходному репо, и (в) не заботился бы о том, что никогда не будет способа определить, была ли информация неверной или устаревший?
Джонатан Хартли
12
Многие лицензии требуют, чтобы вы включили шаблон лицензии в каждый файл по очень веской причине. Если кто-то берет файл или два и перераспределяет их без лицензии, люди, получающие его, понятия не имеют, под какой лицензией он находится, и должны будут отследить его (при условии, что они добросовестны).
nyuszika7h
3
Однако многие модули (scipy, numpy, matplotlib) имеют __version__метаданные, и я думаю, что это хорошо иметь, поскольку они должны быть доступны для программ и быстрой проверки в интерактивном интерпретаторе. Авторство и юридическая информация, однако, находятся в другом файле. Если у вас нет if 'Rob' in __author__:
варианта
34

Ответы выше действительно полны, но если вы хотите, чтобы быстрый и грязный заголовок копировался и вставлялся, используйте это:

#!/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).

Невиш
источник
5
> «В настоящее время каждый файл должен иметь связанную кодировку.» Это кажется вводящим в заблуждение. utf8 является кодировкой по умолчанию, поэтому не стоит ее указывать.
Джонатан Хартли
23

Также см. PEP 263, если вы используете не-ascii набор символов

Аннотация

В этом PEP предлагается ввести синтаксис для объявления кодировки исходного файла Python. Информация о кодировке затем используется анализатором Python для интерпретации файла с использованием заданной кодировки. В частности, это улучшает интерпретацию литералов Unicode в исходном коде и позволяет писать литералы Unicode, используя, например, UTF-8, непосредственно в редакторе, поддерживающем Unicode.

проблема

В Python 2.1 литералы Unicode могут быть написаны только с использованием кодировки на основе Latin-1 «unicode-escape». Это делает среду программирования довольно недружественной для пользователей Python, которые живут и работают в странах, не входящих в Latin-1, таких как многие азиатские страны. Программисты могут писать свои 8-битные строки, используя любимую кодировку, но привязаны к кодировке «unicode-escape» для литералов Unicode.

Предложенное решение

Я предлагаю сделать кодировку исходного кода Python как видимой, так и изменяемой для каждого исходного файла, используя специальный комментарий в верхней части файла для объявления кодировки.

Чтобы Python знал об этой декларации кодирования, необходимо внести ряд изменений в концепцию обработки данных исходного кода Python.

Определение кодировки

Python по умолчанию будет использовать ASCII в качестве стандартной кодировки, если другие подсказки по кодированию не указаны.

Чтобы определить кодировку исходного кода, магический комментарий должен быть помещен в исходные файлы в виде первой или второй строки файла, например:

      # coding=<encoding name>

или (используя форматы, признанные популярными редакторами)

      #!/usr/bin/python
      # -*- coding: <encoding name> -*-

или

      #!/usr/bin/python
      # vim: set fileencoding=<encoding name> :

...

Джон Ла Рой
источник
15
Стоит отметить, что начиная с Python 3, набор символов по умолчанию - UTF-8.
nyuszika7h