Quel est le format d'en-tête commun des fichiers Python?

508

Je suis tombé sur le format d'en-tête suivant pour les fichiers source Python dans un document sur les directives de codage Python:

#!/usr/bin/env python

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

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

Est-ce le format standard des en-têtes dans le monde Python? Quels autres champs / informations puis-je mettre dans l'en-tête? Les gourous de Python partagent vos directives pour de bons en-têtes de source Python :-)

Ashwin Nanjappa
la source
Voici un bon point de départ: PEP 257 , qui parle de Docstrings et des liens vers plusieurs autres documents pertinents.
Peter
41
Peut-être une ligne directrice utile pour ceux qui lisent les différentes réponses à cette question est de considérer à quelles fins ils s'attendent à ce que ces en-têtes de fichier soient utilisés. Si vous avez un cas d'utilisation concret (par exemple, mon avocat dit que les affaires judiciaires sont perdues parce que les développeurs n'ont pas mis les informations de copyright dans chaque fichier), alors ajoutez et maintenez les informations dont vous avez besoin pour ce cas d'utilisation. Sinon, vous vous adonnez à votre fétichisme des TOC.
Jonathan Hartley
haha great @JonathanHartley! Pour mes propres projets, comme vous le dites "je me livre à mon fétichisme des TOC". hahaaha stackoverflow.com/a/51914806/1896134
JayRizzo

Réponses:

577

Toutes ses métadonnées pour le Foobar module.

Le premier est celui docstringdu module, qui est déjà expliqué dans la réponse de Peter .

Comment organiser mes modules (fichiers source)? (Archiver)

La première ligne de chaque fichier doit être #!/usr/bin/env python. Cela permet d'exécuter le fichier comme un script invoquant implicitement l'interpréteur, par exemple dans un contexte CGI.

Ensuite devrait être la docstring avec une description. Si la description est longue, la première ligne doit être un bref résumé qui a du sens en soi, séparé du reste par une nouvelle ligne.

Tout le code, y compris les instructions d'importation, doit suivre la docstring. Sinon, la docstring ne sera pas reconnue par l'interpréteur et vous n'y aurez pas accès dans les sessions interactives (c'est-à-dire via obj.__doc__) ou lors de la génération de documentation avec des outils automatisés.

Importez d'abord les modules intégrés, puis les modules tiers, puis les modifications apportées au chemin et à vos propres modules. En particulier, les ajouts au chemin et aux noms de vos modules sont susceptibles de changer rapidement: les garder au même endroit les rend plus faciles à trouver.

Viennent ensuite les informations sur la paternité. Ces informations doivent suivre ce format:

__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__ = "[email protected]"
__status__ = "Production"

Le statut doit généralement être "Prototype", "Développement" ou "Production". __maintainer__devrait être la personne qui corrigera les bogues et apportera des améliorations en cas d'importation. __credits__diffère de __author__celui qui __credits__inclut les personnes qui ont signalé des corrections de bogues, fait des suggestions, etc. mais qui n'ont pas réellement écrit le code.

Ici , vous avez plus d' informations, la liste __author__, __authors__, __contact__, __copyright__, __license__, __deprecated__, __date__et __version__métadonnées reconnues.

Esteban Küber
la source
7
La création des informations d'en-tête peut-elle en quelque sorte être automatisée pour les nouveaux fichiers?
Hauke
184
Je pense que toutes ces métadonnées après les importations sont une mauvaise idée. Les parties de ces métadonnées qui s'appliquent à un seul fichier (par exemple l'auteur, la date) sont déjà suivies par le contrôle de source. Mettre une copie erronée et obsolète des mêmes informations dans le fichier lui-même me semble mal. Les parties qui s'appliquent à l'ensemble du projet (par exemple licence, versioning) semblent mieux situées au niveau du projet, dans un fichier qui leur est propre, plutôt que dans chaque fichier de code source.
Jonathan Hartley
28
D'accord avec Jonathan Hartley. La personne suivante à hériter du code a trois choix: 1) le mettre à jour à chaque fois qu'il édite le code 2) le laisser tranquille, auquel cas il sera inexact 3) le supprimer tout. L'option 1 est une perte de temps, d'autant plus qu'ils ne sont absolument pas convaincus que les métadonnées étaient à jour au moment de leur réception. Les options 2 et 3 signifient que votre temps à le mettre là-bas en premier lieu a été perdu. Solution: gagnez du temps pour tout le monde et ne le mettez pas là.
spookylukey
77
Il n'y a aucune raison pour que la plupart des fichiers Python aient une ligne shebang.
Mike Graham
15
Par PEP 8, __version__doit suivre directement la docstring principale, avec une ligne vierge avant et après. En outre, il est préférable de définir votre jeu de caractères immédiatement sous le shebang -# -*- coding: utf-8 -*-
Dave Lasley
179

Je privilégie fortement les en-têtes de fichiers minimaux, ce qui signifie simplement:

  • Le hashbang ( #!ligne) s'il s'agit d'un script exécutable
  • Module docstring
  • Importations, regroupées de manière standard, par exemple:
  import os    # standard library
  import sys

  import requests  # 3rd party packages

  import mypackage.mymodule  # local source
  import mypackage.myothermodule  

c'est à dire. trois groupes d'importations, avec une seule ligne blanche entre eux. Au sein de chaque groupe, les importations sont triées. Le dernier groupe, les importations de source locale, peut être soit des importations absolues comme indiqué, soit des importations relatives explicites.

Tout le reste est une perte de temps, d'espace visuel et est activement trompeur.

Si vous avez des clauses de non-responsabilité ou des informations de licence, elles sont enregistrées dans un fichier distinct. Il n'a pas besoin d'infecter tous les fichiers de code source. Votre droit d'auteur devrait en faire partie. Les gens devraient pouvoir le trouver dans votre LICENSEfichier, pas dans un code source aléatoire.

Les métadonnées telles que la paternité et les dates sont déjà conservées par votre contrôle de source. Il n'est pas nécessaire d'ajouter une version moins détaillée, erronée et obsolète des mêmes informations dans le fichier lui-même.

Je ne pense pas qu'il y ait d'autres données que tout le monde doive mettre dans tous leurs fichiers source. Vous pouvez avoir une exigence particulière à cet égard, mais ces choses ne s'appliquent, par définition, qu'à vous. Ils n'ont pas leur place dans les «en-têtes généraux recommandés pour tout le monde».

Jonathan Hartley
la source
23
Je ne pourrais pas être plus d'accord - c'est un péché de répliquer du code à plusieurs endroits, alors pourquoi faire de même pour les informations d'en-tête. Mettez-le dans un seul endroit (racine du projet) et évitez les tracas de maintenir de telles informations sur de très nombreux fichiers.
Graeme
13
Bien que je convienne que le contrôle des sources tend à fournir des informations de paternité plus valides, parfois les auteurs ne distribuent que la source sans donner accès au référentiel, ou peut-être que c'est juste la façon dont la distribution fonctionne, par exemple: installation centralisée à partir de pypi. Ainsi, l'incorporation d'informations sur la paternité en tant qu'en-tête de module est toujours bénéfique.
landau
6
Hey Pram. J'ai du mal à envisager un cas d'utilisation où cela serait réellement utile. Je peux imaginer quelqu'un qui veut connaître les informations sur la paternité du projet dans son ensemble, et il peut obtenir de la valeur à partir d'une liste des principaux contributeurs en un seul endroit central, peut-être le fichier README ou les documents du projet. Mais qui (a) voudrait connaître la paternité des fichiers individuels , et (b) n'aurait pas accès au référentiel source, et (c) ne se soucierait pas qu'il n'y ait jamais de moyen de savoir si les informations étaient incorrectes ou périmé?
Jonathan Hartley
12
De nombreuses licences vous obligent à inclure le passe-partout de licence dans chaque fichier pour une très bonne raison. Si quelqu'un prend un fichier ou deux et les redistribue sans la licence, les personnes qui le reçoivent n'ont aucune idée de la licence sous laquelle il se trouve et devront le retrouver (en supposant qu'ils sont de bonne foi, c'est-à-dire).
nyuszika7h
3
Beaucoup de modules (scipy, numpy, matplotlib) ont des __version__métadonnées, cependant, et je pense que c'est bien d'avoir, car ils devraient être accessibles aux programmes et à vérifier rapidement dans l'interpréteur interactif. La paternité et les informations légales appartiennent cependant à un fichier différent. Sauf si vous avez un cas d'utilisation pourif 'Rob' in __author__:
endolith
34

Les réponses ci-dessus sont vraiment complètes, mais si vous voulez un en-tête rapide et sale à copier-coller, utilisez ceci:

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

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

Pourquoi c'est un bon:

  • La première ligne est destinée aux utilisateurs de * nix. Il choisira l'interpréteur Python dans le chemin utilisateur, donc choisira automatiquement l'interpréteur préféré par l'utilisateur.
  • Le second est l'encodage du fichier. De nos jours, chaque fichier doit avoir un codage associé. UTF-8 fonctionnera partout. Seuls les projets hérités utiliseraient un autre encodage.
  • Et une documentation très simple. Il peut remplir plusieurs lignes.

Voir aussi: https://www.python.org/dev/peps/pep-0263/

Si vous écrivez simplement une classe dans chaque fichier, vous n'avez même pas besoin de la documentation (elle irait à l'intérieur du doc ​​de classe).

neves
la source
5
> "De nos jours, chaque fichier doit être associé à un codage." Cela semble trompeur. utf8 est l'encodage par défaut, il est donc parfaitement correct de ne pas le spécifier.
Jonathan Hartley
23

Voir également PEP 263 si vous utilisez un jeu de caractères non ascii

Abstrait

Ce PEP propose d'introduire une syntaxe pour déclarer l'encodage d'un fichier source Python. Les informations d'encodage sont ensuite utilisées par l'analyseur Python pour interpréter le fichier en utilisant l'encodage donné. Plus particulièrement, cela améliore l'interprétation des littéraux Unicode dans le code source et permet d'écrire des littéraux Unicode en utilisant par exemple UTF-8 directement dans un éditeur compatible Unicode.

Problème

Dans Python 2.1, les littéraux Unicode ne peuvent être écrits qu'en utilisant le codage basé sur Latin-1 "unicode-escape". Cela rend l'environnement de programmation plutôt hostile aux utilisateurs Python qui vivent et travaillent dans des environnements locaux non latins-1 tels que de nombreux pays asiatiques. Les programmeurs peuvent écrire leurs chaînes 8 bits en utilisant l'encodage préféré, mais sont liés à l'encodage "unicode-escape" pour les littéraux Unicode.

Solution proposée

Je propose de rendre l'encodage du code source Python à la fois visible et modifiable par fichier source en utilisant un commentaire spécial en haut du fichier pour déclarer l'encodage.

Pour rendre Python conscient de cette déclaration de codage, un certain nombre de changements de concept sont nécessaires en ce qui concerne la gestion des données de code source Python.

Définition de l'encodage

Python utilisera par défaut ASCII comme codage standard si aucune autre indication de codage n'est donnée.

Pour définir un codage de code source, un commentaire magique doit être placé dans les fichiers source en tant que première ou deuxième ligne du fichier, tel que:

      # coding=<encoding name>

ou (en utilisant des formats reconnus par les éditeurs populaires)

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

ou

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

...

John La Rooy
la source
15
Il convient de noter que depuis Python 3, le jeu de caractères par défaut est UTF-8.
nyuszika7h