PEP 257 auf Russisch. (Docstrings-Vereinbarung)

Hallo Habr. Es gibt Zeiten, in denen Sie so viel wie möglich in die Sprache eintauchen und all ihre Feinheiten verstehen möchten. Im Fall von Python ist eine der besten Möglichkeiten, dies zu tun, das Lesen der Dokumentation und der PEPs auf der offiziellen Website. Ich habe dies zu diesem Zeitpunkt nicht getan, da ich viele der "technischen" Aspekte nicht verstehen konnte und es keine Varianten der russischen Übersetzung gab. Jetzt habe ich mich entschlossen, PEP-257 selbst zu übersetzen, das über die korrekte Dokumentation des Codes informiert, da dies Anfängern sicherlich helfen wird, den wahren Python-Ansatz zum Schreiben von Code besser zu verstehen. Ich habe die Codebeispiele ins Russische übersetzt, aber nur, um die Bedeutung besser zu vermitteln. Versuchen Sie in der realen Programmierung, Dokumentationszeilen auf Englisch zu schreiben. Ich sage auch sofort, dass ich als Synonym für den Begriff "docstring" die Wörter "Dokumentation" und "Dokumentationszeilen" verwendet habe. Kommen wir zur Übersetzung.

Pep257
Titel:Docstrings-Vereinbarung
Autoren:David Goodger <goodger at python.org>, Guido van Rossum <guido at python.org>
Diskussion:doc-sig bei python.org
Status:Aktiv
Eine Art:Informativ
Erstellt:29. Mai 2001
Veröffentlichung:13. Juni 2001

Anmerkung


Dieser PEP dokumentiert die Semantik und Konventionen, die mit der Verwendung von Python-Dokumentzeichenfolgen verbunden sind.

Rechtfertigung


Der Zweck dieses PEP besteht darin, die allgemeine Struktur von Dokumentzeilen zu standardisieren: zu beschreiben, was genau sie enthalten und erklären sollten (wir werden die tatsächliche Markup-Syntax nicht diskutieren). PEP enthält keine strengen Richtlinien, sondern Empfehlungen:
„Konventionelle Konventionen sorgen für Klarheit, Konsistenz, Wartungsfreundlichkeit und fördern gute Programmiergewohnheiten. Aber sie zwingen dich nicht, gegen deinen Willen zu handeln. Das ist Python! "

Tim Peters auf comp.lang.python, 16.06.2001

Wenn Sie allgemein akzeptierte Vereinbarungen vermeiden, werden Sie im schlimmsten Fall zusammengekniffen. Es gibt jedoch einige Anwendungen (z. B. Dokumentationssysteme wie Docutils), mit denen Sie ein besseres Ergebnis erzielen können, wenn Sie die Vereinbarungen kennen und befolgen.

Spezifikation


Was ist ein Docstring?


Eine Dokumentationszeichenfolge ist ein Zeichenfolgenliteral, das die erste Anweisung in einer Modul-, Funktions-, Klassen- oder Methodendefinition ist. Eine solche Zeichenfolge wird verfügbar, wenn das spezielle Attribut __doc__ dieses Objekts verarbeitet wird.

Alle Bibliotheken sowie von ihnen exportierte Funktionen und Klassen müssen über eine Dokumentzeichenfolge verfügen. Öffentliche Methoden (einschließlich des Konstruktors __ init__) müssen ebenfalls dokumentiert sein. Das Paket selbst kann in der Datei __init__.py dokumentiert werden, die sich im entsprechenden Verzeichnis befindet.

String-Literale, die an anderer Stelle im Code enthalten sind, können auch die Rolle der Dokumentation spielen. Sie werden vom Python-Bytecode-Compiler nicht erkannt und sind zur Laufzeit nicht als Objektattribute verfügbar (d. H. Ihnen fehlen Informationen in __ doc__). Es gibt jedoch zwei zusätzliche Arten von Dokumentationszeilen, die mit anderen Softwaretools abgerufen werden:

  1. Zeichenfolgenliterale, die unmittelbar nach einer einfachen Zuweisung auf Modul-, Klassen- oder __init__- Ebene auftreten, werden als "Attributdokumentationszeichenfolgen" bezeichnet. (Attribut docstrings)
  2. Zeichenfolgenliterale, die unmittelbar nach einer anderen Dokumentationszeile auftreten, werden als "zusätzliche Dokumentationszeilen" bezeichnet. (zusätzliche Dokumente)

Weitere Informationen zu Attributen und zusätzlichen Dokumentzeichenfolgen finden Sie in PEP 258, „Docutils-Projektspezifikation“.

[ca. ed. Erklärung von PEP 258]
def f(x):
    """  docstring   __doc__ ."""
    """
     "additional docstrings",   , 
        Docutils.
    """
    return x**2

f.a = 1
""" "attribute docstrings"   : f.a"""

Verwenden Sie aus Gründen der Konsistenz immer die dreifachen doppelten Anführungszeichen um die Dokumentationszeile. Wenn Sie Backslash-Zeichen ("\") verwenden, verwenden Sie in Ihrer Dokumentation die r "" rohe Zeichenfolge in doppelten Anführungszeichen "". Verwenden Sie für Dokumentzeichenfolgen mit Unicode-Zeichen u "" Unicode-Zeichenfolge in dreifachen doppelten Anführungszeichen. [ca. Unicode-Zeichenfolgen haben in Python 3.x ihre Bedeutung verloren.]

Es gibt zwei Arten von Dokumentzeichenfolgen: einzeilige und mehrzeilige.

Einzeilige Dokumentationszeilen


Einzeilige Zeichenfolgen werden für offensichtliche Fälle verwendet und sollten sich wirklich in derselben Zeile befinden. Zum Beispiel:

def kos_root():
    """    root KOS"""
    global _kos_root
    if _kos_root: return _kos_root
    ...

Bemerkungen:

  • . .
  • , . docstring .
  • , .
  • — «», . (« », « »), . , : « ...».

    « » «Return pathname» «Returns pathname». PEP-257 , .
  • «», / ( ). :

    def function(a, b):
        """function(a, b) -> list"""
    

    , C ( ), . . - :

    def function(a, b):
        def function(a, b):
        """ X   ."""
    

    ( -, « X» !)

    , : « », «description» . , , .



Die mehrzeilige Dokumentation besteht aus einer Zusammenfassungszeile, die dieselbe Struktur wie eine einzeilige Dokumentzeichenfolge hat, gefolgt von einer leeren Zeile und einer komplexeren Beschreibung. "Zusammenfassungszeile" kann mittels automatischer Dokumentation verwendet werden; Daher ist es so wichtig, es in einer Zeile zu platzieren und dann in einer Zeile zu passieren. Die Zusammenfassungszeile wird unmittelbar nach den öffnenden Anführungszeichen geschrieben, es ist jedoch zulässig, eine Silbentrennung vorzunehmen und mit der nächsten Zeile zu beginnen. [ca. Nach diesem Satz war ich glücklich, denn es gab Leute, die beharrlich versuchten, mir zu beweisen, dass es auf keinen Fall möglich war, eine Übertragung durchzuführen :-)] Gleichzeitig sollte der gesamte Dokumentstring den gleichen Einzug wie die ersten Anführungszeichen der ersten Zeile haben (siehe Beispiel) unten).

Lassen Sie nach allen in der Klasse verwendeten Dokumentationen (einzeilig oder mehrzeilig) eine leere Zeile. Im Allgemeinen müssen Klassenmethoden durch eine leere Zeile voneinander getrennt werden, daher sollte auch die Klassendokumentationszeile auf diese Weise von der ersten Methode getrennt werden.

Die Dokumentation des Skripts (eigenständiges Programm) ist eine Meldung "über die ordnungsgemäße Verwendung" und wird wahrscheinlich gedruckt, wenn das Skript mit ungültigen oder fehlenden Argumenten aufgerufen wird (oder mit der Option "-h", um "Hilfe" zu erhalten). Eine solche Dokumentationszeile sollte die Funktionalität und Syntax der Skriptparameter sowie die verwendeten Umgebungsvariablen und Dateien beschreiben. Diese Meldung kann sich als ziemlich kompliziert herausstellen (das Handbuch umfasst mehrere Vollbildschirme), sollte jedoch gleichzeitig für neue Benutzer praktisch sein, damit sie den Befehl korrekt verwenden können. Außerdem sollte das Handbuch eine klare Beschreibung aller Parameter und Argumente für erfahrene Benutzer enthalten.

Die Moduldokumentation sollte normalerweise eine Liste der Klassen, Ausnahmen und Funktionen (und aller anderen wichtigen Objekte) enthalten, die mithilfe der Bibliothek exportiert werden, sowie eine einzeilige Erklärung für jede dieser Klassen. (Diese Zusammenfassung enthält in der Regel weniger Details als die Zusammenfassungszeile in der Dokumentzeichenfolge des Objekts selbst.) Die Paketdokumentation (d. H. Die Moduldokumentationszeichenfolge in __init__.py) sollte auch die Module und Unterpakete beschreiben und auflisten, die vom Hauptmodul exportiert wurden.

In der Dokumentation einer Funktion oder Methode sollten deren Verhalten, Argumente, Rückgabewerte, Nebenwirkungen, Ausnahmen und Einschränkungen beschrieben werden, wann sie aufgerufen werden können (falls vorhanden). Sie müssen auch optionale Argumente angeben. Es sollte klargestellt werden, ob die Hauptargumente Teil der Schnittstelle sind.

Die Klassendokumentation sollte ihr Verhalten zusammenfassen und öffentliche Methoden sowie Instanzvariablen auflisten. Wenn die Klasse Unterklassen mit einer zusätzlichen Schnittstelle hat, muss diese Schnittstelle separat angegeben werden (aber alles ist auch in dieser Dokumentation enthalten). Der Klassenkonstruktor muss über eine eigene Dokumentationszeile für die Methode __init__ verfügen. Unabhängige (individuelle) Methoden sollten eine eigene Dokumentation haben.

Wenn eine Klasse ein Nachkomme ist und ihr Verhalten hauptsächlich von der Hauptklasse geerbt wird, muss dies in der Dokumentation erwähnt und mögliche Unterschiede beschrieben werden. Verwenden Sie das Verb „override“, um anzuzeigen, dass eine Methode geändert wurde und die Superclass-Methode daher nicht aufgerufen wird. Verwenden Sie das Verb „erweitert“, wenn die Unterklassenmethode (zusätzlich zu ihrem eigenen Verhalten) die Oberklassenmethode aufruft.

Sie nicht verwenden , um die Emacs Konvention Funktionsargumente oder Methoden in Großbuchstaben zu nennen. Bei Python wird zwischen Groß- und Kleinschreibung unterschieden, und manchmal können Argumentnamen verwendet werden, wenn sie an Schlüssel übergeben werden. Daher muss die Dokumentation echte Variablennamen enthalten. Es ist am besten, jedes Argument in einer separaten Zeile aufzulisten. Zum Beispiel:

def complex(real=0.0, imag=0.0):
    """  .

     :
    real --   (  0.0)
    imag --   (  0.0)
    """
    if imag == 0.0 and real == 0.0:
        return complex_zero
    ...


Wenn nicht die gesamte Dokumentzeichenfolge in die Zeile passt, können Sie die schließenden Anführungszeichen in eine separate Zeile setzen. Somit ist es möglich, den Befehl Emacs zu verwenden: Fill-Paragraph

Docstring-Verarbeitung


Werkzeuge zur Verarbeitung von Dokumentationszeilen sollten die gleiche Anzahl von Einrückungen entfernen, die der minimalen Einrückung aller nicht leeren Zeilen entspricht, beginnend mit der zweiten. Einrückungen in der ersten Zeile der Dokumentation sind nicht signifikant und werden gelöscht. Der relative Einzug späterer Zeilen in der Dokumentzeile bleibt erhalten. Leere Zeilen sollten am Anfang und Ende der Zeile des Dokuments entfernt werden.

Da der Code viel genauer als Wörter ist, ist hier die Implementierung des Algorithmus:

def trim(docstring):
    if not docstring:
        return ''
    #     (  Python)
    #      :
    lines = docstring.expandtabs().splitlines()
    #    (   ):
    indent = sys.maxsize
    for line in lines[1:]:
        stripped = line.lstrip()
        if stripped:
            indent = min(indent, len(line) - len(stripped))
    #   (   ):
    trimmed = [lines[0].strip()]
    if indent < sys.maxsize:
        for line in lines[1:]:
            trimmed.append(line[indent:].rstrip())
    #       :
    while trimmed and not trimmed[-1]:
        trimmed.pop()
    while trimmed and not trimmed[0]:
        trimmed.pop(0)
    #    :
    return '\n'.join(trimmed)

Anmerkung des Übersetzers
, python3 sys.maxint sys.maxsize, .


Die Dokumentation im folgenden Beispiel enthält zwei Zeilenumbrüche und hat daher eine Länge von drei. Die erste und letzte Zeile sind leer:

def foo ():
    """
       .
    """

Wir veranschaulichen:

>>> print repr(foo.__doc__)
'\n        .\n    '
>>> foo.__doc__.splitlines()
['', '        .', '    ']
>>> trim(foo.__doc__)
'    .'

Daher sind nach der Verarbeitung die folgenden Dokumentationszeilen gleichwertig:

def foo():
    """ 
     .
    """

def bar():
    """
     
     .
    """

Anmerkung des Übersetzers
inspect, , : inspect.cleandoc(function.__doc__)


All Articles