22.3 Automatisches Erstellen einer Dokumentation – epydoc 

Wenn Sie Ihre Programme und Module an Benutzer und andere Entwickler weitergeben, ist eine gute Dokumentation sehr wichtig. Ohne vernünftige Funktionsbeschreibung ist selbst das beste Programm wertlos, da es zu aufwendig ist, die Funktionsweise allein aus dem Quellcode herauszulesen oder durch Ausprobieren zu erahnen.
Von Programmierern wird das Schreiben von Dokumentationen oft als lästig empfunden, weil es verhältnismäßig viel Zeit in Anspruch nimmt, ohne die Programme selbst zu verbessern. Aus diesem Grund gibt es auch in der Python-Welt viele Module und Programme, die nicht ausreichend dokumentiert sind.
Es gibt allerdings Werkzeuge und Methoden, um das Schreiben von Dokumentationen so einfach wie möglich zu machen. Wir werden uns in diesem Abschnitt mit dem Programm epydoc beschäftigen, das Python-Programme anhand ihres Quellcodes dokumentieren kann. Das Werkzeug epydoc analysiert den Programmtext und sammelt insbesondere die Informationen aus den Docstrings. Die gesammelten Informationen werden aufbereitet und als HTML- oder PDF-Datei exportiert.
Abbildung 22.1 Beispiel für eine Dokumentation mit epydoc
Das Programm epydoc selbst ist in Python geschrieben und deshalb auf allen Python-Plattformen lauffähig. Sie können die aktuellste Version von der Projekt-Homepage unter http://epydoc.sourceforge.net herunterladen. [Falls Sie Linux einsetzen, lohnt sich außerdem ein Blick in die Paketliste Ihrer Distribution. Es ist recht wahrscheinlich, dass dort bereits ein Paket mit epydoc bereitsteht. ]
Benutzung von epydoc
Nach der Installation können Sie epydoc per Konsole aufrufen, wobei der Befehl zum Aufruf unter Unix »epydoc« und unter Windows »epydoc.py« lautet. Wir werden im weiteren Verlauf des Kapitels die Unix-Variante verwenden. Windows-Benutzer müssen beim Nachvollziehen der Aufrufe ein ».py« an »epydoc« anhängen.
Zu epydoc existiert außerdem eine grafische Benutzeroberfläche, die aber aufgrund ihrer eingeschränkten Möglichkeiten nicht besprochen wird.
Im einfachsten Fall ruft man epydoc mit den Modulen als Parameter auf, die man dokumentieren möchte. Voraussetzung für eine erfolgreiche Dokumentationsgenerierung ist, dass die übergebenen Module von Python importiert werden können. Die Module müssen sich also unter dem Pfad befinden, zu dem epydoc ausgeführt wird, oder Standardmodule sein. Als Beispiel erzeugen wir die Dokumentation des Standardmoduls time:
$ epydoc time
Nach dem Aufruf gibt es einen neuen Ordner namens html im aktuellen Arbeitsverzeichnis, der die Dokumentation des Moduls time im HTML-Format enthält.
Um die Erzeugung der Dokumentation anzupassen, kann man epydoc eine Reihe weiterer Parameter übergeben, von denen die folgende Tabelle die drei wichtigsten zeigt:
| Parameter | Beschreibung |
|
--html
|
Erzeuge die Dokumentation im HTML-Format (Standardeinstellung) |
|
--pdf
|
Generiere eine PDF-Datei, die die Dokumentation enthält. |
|
--output DIR
|
Schreibe die Dokumentation in das Verzeichnis DIR. Standardmäßig werden je nach Format die Ordnernamen html oder pdf verwendet. |
Um beispielsweise die Dokumentation des Moduls time als PDF im Verzeichnis time_dokumentation zu erzeugen, dient folgender Aufruf:
$ epydoc --pdf --output time_documentation time
22.3.1 Docstrings und ihre Formatierung für epydoc 

Die wichtigste Informationsquelle für epydoc stellen die Docstrings dar. [Wir haben Docstrings in Abschnitt 13.3 behandelt. ] Allerdings gibt es in Python keine Docstrings für Variablen und Klassenmember, die aber oft auch dokumentiert werden müssen. Deshalb führt epydoc zwei Notationen ein, um auch solche Elemente mit Dokumentation versehen zu können:
| 1. | Steht in der Zeile hinter einer Wertezuweisung ein String-Literal, so wird dieses als Docstring für die Variable interpretiert, der der Wert zugewiesen wurde. |
| 2. | Stehen unmittelbar vor einer Wertezuweisung Kommentare, die durch die Zeichenfolge #: eingeleitet werden, interpretiert epydoc die Kommentare als Docstrings für die Variable, der der Wert zugewiesen wurde. |
Damit kann man die Attribute X und Y der Klasse A wie folgt dokumentieren:
class A(object): X = 10 """ A.X speichert eine Zahl und wird mit 10 initialisiert """ #: Der Klassenmember A.Y speichert eine Zahl und wird #: mit 1337 initialisiert Y = 1337 pass
In diesem Beispiel würde epydoc das Klassenattribut A.X mit dem Docstring "A.X speichert eine Zahl und wird mit 10 initialisiert" verknüpfen und A.Y den Docstring "Der Klassenmember A.Y speichert eine Zahl und wird\nmit 1337 initialisiert" zuordnen. [Der Zeilenvorschub im Docstring von A.Y bleibt erhalten, wie das »\n« andeutet. ]
Die Sprache Epytext
Damit epydoc die Docstrings richtig interpretiert und im Ergebnis auch so angezeigt wie von Ihnen gewünscht, gibt es einige Regeln, die Sie beim Schreiben von Docstrings beachten sollten, wenn Sie epydoc für die Dokumentationsgenerierung verwenden möchten.
Diese Regeln werden von der epydoc-spezifischen, sehr einfachen Beschreibungssprache Epytext festgelegt. Epytext soll möglichst intuitiv verwendbar sein und ist deshalb relativ elementar gehalten.
Jeder Docstring besteht gemäß Epytext aus mehreren Blöcken, die durch Leerzeilen voneinander getrennt sind. Bei der Interpretation durch epydoc werden innerhalb eines Blocks Leerzeilen, Zeilenvorschübe und sonstige Whitespaces zu einzelnen Leerzeichen zusammengefasst.
Die folgende Tabelle zeigt eine Funktion namens test, die in ihrem Docstring drei Textblöcke enthält:
| Python-Code | Generierte Dokumentation |
|
Dies ist der erste Block, der in der Ausgabe vom nachstehenden abgegrenzt wird. Ein weiterer Block. |
Wichtig ist, dass Epytext genau wie Python selbst die Einrückung benutzt, um zu entscheiden, welche Zeilen zu einem Block gehören. Deshalb müssen im letzten Beispiel die vier Zeilen des ersten Blocks alle auf einer Einrücktiefe stehen.
Man kann Blöcke ineinander verschachteln, indem man die Einrücktiefe vergrößert:
| Python-Code | Generierte Dokumentation |
|
Dieser Block hat einen untergeordneten Block. Ich bin untergeordnet. Ich nicht. |
Neben einfachen Textblöcken gibt es andere Blöcke, die durch spezielle Zeichen am Anfang eingeleitet werden. Die folgende Tabelle gibt eine kurze Übersicht über eine Auswahl der unterstützten Blocktypen:
| Zeichen | Blocktyp |
|
- |
Listenelement ohne Nummerierung |
|
1. |
Nummeriertes Listenelement. Anstelle der »1« können beliebige Zahlen stehen. Auch Punkte können zur Gliederung der Liste verwendet werden, z. B. »1.3.2.« |
|
>>> |
Doctest-Block. Damit werden Tests des Doctest-Moduls eingeleitet (siehe hierzu Abschnitt 21.5.1). |
|
@ |
Felder, die bestimmte Informationen zu Parametern enthalten |
Listen
Listenelemente können mehrere Blöcke und auch weitere Listen enthalten. Alle in einer Liste enthaltenen Blöcke müssen genauso tief wie oder tiefer als das einleitende Zeichen eingerückt werden:
| Python-Code | Generierte Dokumentation |
|
1. Erstes Listenelement einer geordneten Liste. 2. Noch ein Element. Man beachte die Einruecktiefe. 3. Das letzte Element der Liste. – Eine Liste ohne Nummerierung. – Listenelemente muessen nicht zwingend durch Leerzeilen voneinander getrennt werden. |
Listen können genau wie Textblöcke ineinander verschachtelt werden. Dabei müssen sie tiefer als der übergeordnete Block eingerückt sein.
Doctest-Abschnitte
Doctest-Blöcke werden durch drei Größerzeichen, >>>, eingeleitet und müssen von den umliegenden Blöcken durch Leerzeilen getrennt werden. Außerdem dürfen sie selbst keine Leerzeilen enthalten. Weitere Informationen zu Doctest finden Sie in Abschnitt 21.5.1.
Felder
Sogenannte Felder dienen dazu, spezielle Informationen wie Parameterbeschreibungen anzugeben. Sie werden von einem @ eingeleitet, das von einem Schlüsselwort gefolgt wird. Dieses Schlüsselwort gibt an, welche Information der folgende Block enthält. Die Zeichenfolge @param leitet beispielsweise eine Parameterbeschreibung ein.
Wir beschränken uns hier aufgrund der Fülle von Schlüsselwörtern auf die wichtigsten: param, type und return. Die Verwendung dieser Felder zeigt das folgende Beispiel:
| Python-Code | Generierte Dokumentation |
|
Parameters: x – Gibt den Zahlenwert an, dessen Quadrat bestimmt werden soll. (type=int oder float) Returns: Gibt das Quadrat von x zurueck. |
Sonstige Formatierungsanweisungen
Neben den bisher besprochenen eher strukturellen Formatierungen kann auch das Aussehen der Ausgabe direkt verändert werden. Dazu zählt beispielsweise das Verändern des Schriftbilds zu Fett oder Kursiv. Da diese Art der Formatierung innerhalb von beliebigen Blöcken vorkommen kann, wird sie Inline Markup (dt. Eingebettete Auszeichnung) genannt.
Inline Markup hat immer die Form x{...}, wobei x ein einzelner Großbuchstabe ist, der die Art der Auszeichnung angibt, und ... den zu formatierenden String symbolisiert.
Beispielsweise steht der Buchstabe I für kursiven Text (von engl. italic). Die Inline-Markup-Anweisung I{Hallo Welt} gibt also den String Hallo Welt kursiv aus.
In der nachstehenden Tabelle sind die wichtigsten Buchstaben für das Inline Markup aufgeführt:
| Buchstabe | Bedeutung |
|
I |
Kursiver Text |
|
B |
Fetter Text |
|
C |
Quellcodegerechte Formatierung. Schrift mit gleicher Breite für alle Zeichen. |
|
M |
Mathematische Ausdrücke |
|
U |
Interpretiert den Inhalt der Klammern als URL und erzeugt in der Ausgabe einen Hyperlink zu dieser Adresse |
|
E |
Escaping – Es verhindert, dass das Zeichen zwischen den geschweiften Klammern als Epytext-Anweisung interpretiert wird. Steht mehr als ein Zeichen zwischen den Klammern, wird dies als kodiertes Sonderzeichen aufgefasst. Mit »E{rb}« und »E{lb}« lassen sich Beispielsweise die geschweiften Klammern } und { kodieren. |
Insbesondere der Buchstabe E ist sehr wichtig, um zu verhindern, dass Teile von Docstrings, die zufällig gültige Epytext-Anweisungen ergeben, nicht fälschlicherweise als solche interpretiert werden. Das folgende Beispiel zeigt einen Docstring, der ohne Escaping ein unbeabsichtigtes Listenelement hätte:
def funktion(): """ Eine komplett sinnlose Funktion, die E{-} wenn sie richtig angewendet wird - vielleicht doch einmal von Nutzen sein kann... """ return 10
Stünde anstelle von E{-} ein einfacher Bindestrich (-), würde die zweite Zeile des Docstrings als Element einer Liste ohne Nummerierung interpretiert.
Ausblick
Das Programm epydoc ist sehr mächtig und umfangreich. Dieses Kapitel sollte Ihnen einen kleinen Einblick in seine Funktionalität gewähren, wobei jedoch nicht alle Aspekte berücksichtigt werden konnten.
Wenn Sie sich ausführlich mit epydoc beschäftigen möchten, empfehlen wir ihnen die sehr gute Dokumentation auf der Homepage. Diese finden Sie unter der folgenden Adresse:
http//epydoc.sourceforge.net





bestellen





