Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 224 – Attribut-Docstrings

Autor:
Marc-André Lemburg <mal at lemburg.com>
Status:
Abgelehnt
Typ:
Standards Track
Erstellt:
23.-Aug-2000
Python-Version:
2.1
Post-History:


Inhaltsverzeichnis

Warnung

Dieser PEP wurde abgelehnt.

×

Siehe Kommentare von unserem BDFL für weitere Informationen.

Einleitung

Dieses PEP beschreibt den „Attribut-Docstring“-Vorschlag für Python 2.0. Dieses PEP verfolgt den Status und die Zuständigkeit dieser Funktion. Es enthält eine Beschreibung der Funktion und skizziert die notwendigen Änderungen zur Unterstützung der Funktion. Die CVS-Revisionshistorie dieser Datei enthält die maßgebliche historische Aufzeichnung.

Begründung

Dieses PEP schlägt eine kleine Ergänzung dazu vor, wie Python derzeit Docstrings in Python-Code einbettet.

Python behandelt derzeit nur den Fall von Docstrings, die direkt nach einer Klassendefinition, einer Funktionsdefinition oder als erster String-Literal in einem Modul erscheinen. Die String-Literale werden den betreffenden Objekten unter dem Attribut __doc__ hinzugefügt und sind von da an für Introspektionswerkzeuge verfügbar, die die enthaltenen Informationen für Hilfe-, Debugging- und Dokumentationszwecke extrahieren können.

Docstrings, die an anderen als den genannten Stellen erscheinen, werden einfach ignoriert und führen zu keiner Codeerzeugung.

Hier ist ein Beispiel

class C:
    "class C doc-string"

    a = 1
    "attribute C.a doc-string (1)"

    b = 2
    "attribute C.b doc-string (2)"

Die Docstrings (1) und (2) werden derzeit vom Python-Bytecode-Compiler ignoriert, könnten aber offensichtlich gut zur Dokumentation der ihnen vorangehenden benannten Zuweisungen verwendet werden.

Dieses PEP schlägt vor, auch diese Fälle zu nutzen, indem Semantiken für die Hinzufügung ihres Inhalts zu den Objekten vorgeschlagen werden, in denen sie unter neuen generierten Attributnamen erscheinen.

Die ursprüngliche Idee hinter diesem Ansatz, die auch das obige Beispiel inspiriert hat, war die Ermöglichung von Inline-Dokumentation von Klassenattributen, die derzeit nur im Docstring der Klasse oder mittels Kommentaren dokumentiert werden können, die für die Introspektion nicht verfügbar sind.

Implementierung

Docstrings werden vom Bytecode-Compiler als Ausdrücke behandelt. Die aktuelle Implementierung behandelt die wenigen oben genannten Stellen speziell, um diese Ausdrücke zu nutzen, ignoriert aber ansonsten die Strings vollständig.

Um die Nutzung dieser Docstrings zur Dokumentation benannter Zuweisungen (was der natürliche Weg zur Definition von z. B. Klassenattributen ist) zu ermöglichen, muss der Compiler den Namen der zuletzt zugewiesenen Variablen verfolgen und diesen Namen dann verwenden, um den Inhalt des Docstrings einem Attribut des enthaltenden Objekts zuzuweisen, indem er ihn als Konstante speichert, die dann während der Objekterstellungszeit dem Namensraum des Objekts hinzugefügt wird.

Um Funktionen wie Vererbung und Verbergen von Pythons speziellen Attributen (die mit führenden und nachgestellten doppelten Unterstrichen) zu erhalten, muss eine spezielle Namens-Mangling angewendet werden, die den Docstring eindeutig als zu der Namenszuweisung gehörend identifiziert und es ermöglicht, den Docstring später durch Inspizieren des Namensraums zu finden.

Das folgende Namens-Mangling-Schema erreicht all dies

__doc_<attributename>__

Um den Namen der zuletzt zugewiesenen Variablen zu verfolgen, speichert der Bytecode-Compiler diesen Namen in einer Variablen der kompilierten Struktur. Diese Variable ist standardmäßig NULL. Wenn er einen Docstring sieht, prüft er die Variable und verwendet den Namen als Basis für das obige Namens-Mangling, um eine implizite Zuweisung des Docstrings an den mangled Namen zu erzeugen. Dann setzt er die Variable auf NULL zurück, um doppelte Zuweisungen zu vermeiden.

Wenn die Variable nicht auf einen Namen zeigt (d.h. NULL ist), werden keine Zuweisungen vorgenommen. Diese werden wie zuvor ignoriert. Alle klassischen Docstrings fallen unter diesen Fall, so dass keine doppelten Zuweisungen erfolgen.

Im obigen Beispiel würde dies zu den folgenden neuen Klassenattributen führen

C.__doc_a__ == "attribute C.a doc-string (1)"
C.__doc_b__ == "attribute C.b doc-string (2)"

Ein Patch zur aktuellen CVS-Version von Python 2.0, der das obige implementiert, ist auf SourceForge unter [1] verfügbar.

Vorbehalte der Implementierung

Da die Implementierung die Variable der kompilierten Struktur beim Verarbeiten eines Nicht-Ausdrucks, z. B. einer Funktionsdefinition, nicht zurücksetzt, bleibt der zuletzt zugewiesene Name aktiv, bis entweder die nächste Zuweisung oder das nächste Vorkommen eines Docstrings erfolgt.

Dies kann zu Fällen führen, in denen der Docstring und die Zuweisung durch andere Ausdrücke getrennt sein können

class C:
    "C doc string"

    b = 2

    def x(self):
        "C.x doc string"
         y = 3
         return 1

    "b's doc string"

Da die Definition der Methode „x“ derzeit nicht die verwendete Zuweisungsnamenvariable zurücksetzt, ist sie noch gültig, wenn der Compiler auf den Docstring „b’s doc string“ trifft und die Zeichenkette somit __doc_b__ zugewiesen wird.

Eine mögliche Lösung für dieses Problem wäre das Zurücksetzen der Namensvariable für alle Nicht-Ausdrucksknoten im Compiler.

Mögliche Probleme

Auch wenn höchst unwahrscheinlich, könnten Attribut-Docstrings versehentlich an den Wert des Attributs angehängt werden

class C:
    x = "text" \
        "x's docstring"

Der nachgestellte Schrägstrich würde den Python-Compiler dazu veranlassen, den Attributwert und den Docstring zu verketten.

Ein moderner Syntaxhervorhebungs-Editor würde diesen Unfall jedoch leicht sichtbar machen, und durch einfaches Einfügen von Leerzeilen zwischen der Attributdefinition und dem Docstring können Sie die mögliche Verkettung vollständig vermeiden, sodass das Problem vernachlässigbar ist.

Ein weiteres mögliches Problem ist die Verwendung von dreifach angeführten Strings, um Teile Ihres Codes auszukommentieren.

Wenn zufällig eine Zuweisung direkt vor dem Beginn des Kommentar-Strings erfolgt, behandelt der Compiler den Kommentar als Attribut-Docstring und wendet die obige Logik darauf an.

Abgesehen von der Generierung eines Docstrings für ein ansonsten undokumentiertes Attribut gibt es keine Brüche.

Kommentare von unserem BDFL

Frühe Kommentare zum PEP von Guido

Ich mag die Idee von Attribut-Docstrings „irgendwie“ (was bedeutet, dass sie für mich keine große Bedeutung hat), aber es gibt zwei Dinge, die mir an Ihrem aktuellen Vorschlag nicht gefallen
  1. Die von Ihnen vorgeschlagene Syntax ist zu mehrdeutig: Wie Sie sagen, werden eigenständige String-Literale für andere Zwecke verwendet und könnten plötzlich zu Attribut-Docstrings werden.
  2. Auch die Zugriffsmethode (__doc_<attrname>__) gefällt mir nicht.

Die Antwort des Autors

> 1. The syntax you propose is too ambiguous: as you say, stand-alone
>    string literal are used for other purposes and could suddenly
>    become attribute docstrings.

Dies kann behoben werden, indem einige zusätzliche Prüfungen im Compiler eingeführt werden, um das „doc attribute“-Flag in der Compiler-Struktur zurückzusetzen.

> 2. I don't like the access method either (``__doc_<attrname>__``).

Jeder andere Name ist in Ordnung. Er muss nur diese Kriterien erfüllen

  • muss mit zwei Unterstrichen beginnen (um mit __doc__ übereinzustimmen)
  • muss mit einer Form der Inspektion extrahierbar sein (z. B. durch Verwendung einer Namenskonvention, die einen festen Namensbestandteil enthält)
  • muss mit der Klassenvererbung kompatibel sein (d. h. als Attribut gespeichert werden)

Später im März äußerte sich Guido im März 2001 zu diesem PEP (auf python-dev). Hier sind seine Gründe für die Ablehnung, die in einer privaten E-Mail an den Autor dieses PEP erwähnt werden

Es mag nützlich sein, aber ich hasse wirklich die vorgeschlagene Syntax.

a = 1
"foo bar"
b = 1

Ich habe wirklich keine Möglichkeit zu wissen, ob „foo bar“ ein Docstring für a oder für b ist.

Sie können diese Konvention verwenden

a = 1
__doc_a__ = "doc string for a"

Dies macht es zur Laufzeit verfügbar.

> Are you completely opposed to adding attribute documentation
> to Python or is it just the way the implementation works ? I
> find the syntax proposed in the PEP very intuitive and many
> other users on c.l.p and in private emails have supported it
> at the time I wrote the PEP.

Es ist nicht die Implementierung, es ist die Syntax. Sie vermittelt keine klare genug Kopplung zwischen der Variablen und dem Docstring.

Referenzen


Quelle: https://github.com/python/peps/blob/main/peps/pep-0224.rst

Zuletzt geändert: 2024-04-14 20:08:31 GMT