Qual è il formato di intestazione comune dei file Python?


508

Mi sono imbattuto nel seguente formato di intestazione per i file sorgente Python in un documento sulle linee guida per la codifica Python:

#!/usr/bin/env python

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

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

È questo il formato standard delle intestazioni nel mondo Python? Quali altri campi / informazioni posso inserire nell'intestazione? I guru di Python condividono le tue linee guida per le buone intestazioni dei sorgenti di Python :-)


Ecco un buon punto di partenza: PEP 257 , che parla di Docstrings e collega a molti altri documenti pertinenti.
Peter,

41
Forse una linea guida utile per coloro che leggono le diverse risposte a questa domanda è quella di considerare per quali scopi si aspettano che queste intestazioni di file vengano utilizzate. Se hai un caso d'uso concreto (ad esempio il mio avvocato dice che i casi giudiziari sono persi perché gli sviluppatori non sono riusciti a inserire le informazioni sul copyright in ogni singolo file.) Quindi aggiungi e gestisci le informazioni necessarie per quel caso d'uso. Altrimenti, stai solo indulgendo al tuo feticcio da DOC.
Jonathan Hartley,

haha great @JonathanHartley! Per i miei progetti, come dici tu "concedo il mio feticcio OCD". hahaaha stackoverflow.com/a/51914806/1896134
JayRizzo

Risposte:


577

Sono tutti metadati per il Foobarmodulo.

Il primo è il docstringmodulo, che è già spiegato nella risposta di Peter .

Come organizzo i miei moduli (file sorgente)? (Archivio)

La prima riga di ogni file dovrebbe essere #!/usr/bin/env python. Ciò consente di eseguire il file come script invocando implicitamente l'interprete, ad esempio in un contesto CGI.

Il prossimo dovrebbe essere il docstring con una descrizione. Se la descrizione è lunga, la prima riga dovrebbe essere un breve riassunto che abbia un senso da sola, separata dal resto da una nuova riga.

Tutto il codice, comprese le dichiarazioni di importazione, dovrebbe seguire la documentazione. Altrimenti, il docstring non verrà riconosciuto dall'interprete e non avrai accesso ad esso in sessioni interattive (cioè attraverso obj.__doc__) o durante la generazione di documentazione con strumenti automatizzati.

Importa prima i moduli integrati, seguiti dai moduli di terze parti, seguiti da eventuali modifiche al percorso e ai tuoi moduli. In particolare, è probabile che le aggiunte al percorso e ai nomi dei tuoi moduli cambino rapidamente: tenerli in un posto li rende più facili da trovare.

Il prossimo dovrebbe essere informazioni sulla paternità. Queste informazioni dovrebbero seguire questo formato:

__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"

Lo stato dovrebbe in genere essere "Prototipo", "Sviluppo" o "Produzione". __maintainer__dovrebbe essere la persona che risolverà i bug e apporterà miglioramenti se importato. __credits__differisce da __author__quello che __credits__include le persone che hanno segnalato correzioni di bug, suggerimenti, ecc. ma che in realtà non hanno scritto il codice.

Qui si hanno più informazioni, elencando __author__, __authors__, __contact__, __copyright__, __license__, __deprecated__, __date__e __version__metadati come riconosciuto.


7
La creazione delle informazioni dell'intestazione può in qualche modo essere automatizzata per i nuovi file?
Hauke,

184
Penso che tutti questi metadati dopo le importazioni siano una cattiva idea. Le parti di questi metadati che si applicano a un singolo file (ad esempio autore, data) sono già monitorate dal controllo del codice sorgente. Mettere una copia errata e obsoleta delle stesse informazioni nel file stesso mi sembra sbagliato. Le parti che si applicano all'intero progetto (ad es. Licenza, versioning) sembrano meglio posizionate a livello di progetto, in un file a parte, piuttosto che in ogni file di codice sorgente.
Jonathan Hartley,

28
Concordo totalmente con Jonathan Hartley. La persona successiva a ereditare il codice ha tre possibilità: 1) aggiornarlo ogni volta che modifica il codice 2) lasciarlo da solo, nel qual caso sarà inaccurato 3) eliminarlo tutto. L'opzione 1 è una perdita di tempo, soprattutto perché non hanno la certezza assoluta che i metadati siano aggiornati al momento della ricezione. Le opzioni 2 e 3 indicano che il tuo tempo nel metterlo lì in primo luogo è stato sprecato. Soluzione: risparmia il tempo di tutti e non metterlo lì.
spookylukey,

77
Non c'è motivo per la maggior parte dei file Python di avere una linea shebang.
Mike Graham,

15
Per PEP 8, __version__deve seguire direttamente la documentazione principale, con una riga vuota prima e dopo. Inoltre, è consigliabile definire il set di caratteri immediatamente sotto lo shebang -# -*- coding: utf-8 -*-
Dave Lasley

179

Prediligo fortemente le intestazioni di file minime, intendo semplicemente:

  • L'hashbang ( #!linea) se questo è uno script eseguibile
  • Docstring del modulo
  • Importazioni, raggruppate in modo standard, ad esempio:
  import os    # standard library
  import sys

  import requests  # 3rd party packages

  import mypackage.mymodule  # local source
  import mypackage.myothermodule  

vale a dire. tre gruppi di importazioni, con un'unica riga vuota tra di loro. All'interno di ciascun gruppo, le importazioni sono ordinate. Il gruppo finale, le importazioni da fonti locali, possono essere importazioni assolute come mostrato o importazioni relative esplicite.

Tutto il resto è una perdita di tempo, spazio visivo ed è attivamente fuorviante.

Se hai dichiarazioni di non responsabilità legali o informazioni sulla licenza, queste vanno in un file separato. Non è necessario infettare tutti i file di codice sorgente. Il tuo copyright dovrebbe far parte di questo. Le persone dovrebbero essere in grado di trovarlo nel tuo LICENSEfile, non nel codice sorgente casuale.

Metadati come la paternità e le date sono già gestiti dal controllo del codice sorgente. Non è necessario aggiungere una versione meno dettagliata, errata e non aggiornata delle stesse informazioni nel file stesso.

Non credo ci siano altri dati che tutti devono inserire in tutti i loro file di origine. Potresti avere dei requisiti particolari per farlo, ma tali cose si applicano, per definizione, solo a te. Non hanno posto in "intestazioni generali consigliate a tutti".


23
Non potrei essere più d'accordo: è un peccato replicare il codice in più punti, quindi perché fare lo stesso per le informazioni di intestazione. Mettilo in un unico posto (radice del progetto) ed evita il fastidio di conservare tali informazioni su molti, molti file.
Graeme,

13
Anche se concordo sul fatto che il controllo del codice sorgente tende a fornire informazioni di paternità più valide, a volte gli autori distribuiscono il codice sorgente solo senza dare accesso al repository, o forse è così che funziona la distribuzione, ad esempio: installazione centralizzata da pypi. Pertanto, l'incorporazione delle informazioni sulla paternità come intestazione del modulo è ancora utile.
carrozzina

6
Ehi carrozzina. Ho problemi a prevedere un caso d'uso in cui ciò è effettivamente utile. Posso immaginare qualcuno che desideri conoscere le informazioni sull'autore per il progetto nel suo insieme e possono ottenere valore da un elenco dei principali collaboratori in un unico posto centrale, forse il README o i documenti del progetto. Ma chi (a) vorrebbe conoscere la paternità dei singoli file e (b) non avrebbe accesso al repository di origine, e (c) non si preoccuperebbe che non ci sia mai un modo per dire se le informazioni erano errate o obsoleto?
Jonathan Hartley,

12
Molte licenze richiedono di includere la licenza boilerplate in ciascun file per un motivo molto valido. Se qualcuno prende un file o due e li ridistribuisce senza la licenza, le persone che lo ricevono non hanno idea di quale sia la licenza e dovranno rintracciarla (supponendo che siano in buona fede, cioè).
nyuszika7h

3
Molti moduli (scipy, numpy, matplotlib) hanno __version__metadati, tuttavia, e penso che sia utile, dato che dovrebbero essere accessibili ai programmi e da controllare rapidamente nell'interprete interattivo. La paternità e le informazioni legali appartengono tuttavia a un file diverso. A meno che tu non abbia un caso d'uso perif 'Rob' in __author__:
endolith

34

Le risposte sopra sono davvero complete, ma se vuoi copiare e incollare un'intestazione veloce e sporca, usa questo:

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

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

Perché questo è buono:

  • La prima riga è per gli utenti * nix. Sceglierà l'interprete Python nel percorso dell'utente, quindi sceglierà automaticamente l'interprete preferito dall'utente.
  • Il secondo è la codifica del file. Al giorno d'oggi ogni file deve avere una codifica associata. UTF-8 funzionerà ovunque. Solo i progetti legacy utilizzerebbero altre codifiche.
  • E una documentazione molto semplice. Può riempire più righe.

Vedi anche: https://www.python.org/dev/peps/pep-0263/

Se scrivi semplicemente una classe in ciascun file, non hai nemmeno bisogno della documentazione (andrebbe all'interno del documento di classe).


5
> "Oggi ogni file deve avere una codifica associata." Questo sembra fuorviante. utf8 è la codifica predefinita, quindi è perfettamente corretto non specificarla.
Jonathan Hartley,

23

Vedi anche PEP 263 se stai usando un set di caratteri non ASCII

Astratto

Questo PEP propone di introdurre una sintassi per dichiarare la codifica di un file sorgente Python. Le informazioni di codifica vengono quindi utilizzate dal parser Python per interpretare il file utilizzando la codifica fornita. In particolare, ciò migliora l'interpretazione dei letterali Unicode nel codice sorgente e consente di scrivere letterali Unicode usando ad esempio UTF-8 direttamente in un editor compatibile con Unicode.

Problema

In Python 2.1, i letterali Unicode possono essere scritti solo usando la codifica "unicode-escape" basata su Latin-1. Questo rende l'ambiente di programmazione piuttosto ostile agli utenti di Python che vivono e lavorano in locali non latini-1 come molti dei paesi asiatici. I programmatori possono scrivere le loro stringhe a 8 bit utilizzando la codifica preferita, ma sono associati alla codifica "unicode-escape" per i letterali Unicode.

La soluzione proposta

Propongo di rendere il codice sorgente Python codificante sia visibile che modificabile in base al file sorgente utilizzando un commento speciale nella parte superiore del file per dichiarare la codifica.

Per rendere Python consapevole di questa dichiarazione di codifica sono necessarie alcune modifiche al concetto riguardo alla gestione dei dati del codice sorgente di Python.

Definire la codifica

Python verrà automaticamente impostato su ASCII come codifica standard se non vengono forniti altri suggerimenti per la codifica.

Per definire una codifica del codice sorgente, un commento magico deve essere inserito nei file sorgente come prima o seconda riga nel file, ad esempio:

      # coding=<encoding name>

o (utilizzando formati riconosciuti da editor popolari)

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

o

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

...


15
Vale la pena notare che da Python 3, il set di caratteri predefinito è UTF-8.
nyuszika7h
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.