Zeichnen eines Aufrufdiagramms

Ich behalte eine alte in Python geschriebene Codebasis bei. Insbesondere gibt es einen komplexen Code, der von einem Modul andere Funktionen aufruft von anderen Modulen, die andere Funktionen aufrufen und so weiter. Es ist nicht OOP, sondern nur Funktionen und Module.
Ich habe versucht zu verfolgen, wo der Fluss beginnt und endet, wenn ich die Hauptfunktion aufrufe, aber ich habe das Gefühl, ich muss zeichnen Dies liegt daran, dass ich mich in den Unteraufrufen verliere.

Was mich betrifft, ist, dass jede Funktion mehrere externe Funktionen in ihrem Körper aufruft, um ihre Aufgabe abzuschließen und den Wert an den Aufrufer zurückzugeben.

Wie kann ich das zeichnen? Das heißt, welche Art von Diagramm / Grafik wäre geeignet, um diese Art von Verhalten / Code zu dokumentieren?

Ich denke also nicht, dass es nützlich wäre, ein UML-Diagramm zu zeichnen , weder ein Flussdiagramm. Vielleicht ein Anrufdiagramm?

Kommentare

  • Sauerstoff – generiert Anruf- / Anruferdiagramme, I ' Ich bin mir nicht sicher, wie viel Unterstützung es für Python hat. Ich weiß, dass Sie Python-Code dafür dokumentieren können.
  • Ich ' habe Pycallgraph ausprobiert, aber ' ist es auch kompliziert / zu tief, um es zu benutzen. Dies liegt an der Komplexität meines Codes, da er einfaches Python mit Django und externem Aufruf der API-URL mischt. Deshalb wollte ich es von Hand zeichnen, nur unter Berücksichtigung des relevanten Teils, den ich brauche. Das Problem ist, dass ich ' nicht weiß, welche Art von Grafik verwendet werden soll, um das System vollständig zu verstehen.
  • Wenn dies nur dazu dient, Ihnen das Verständnis zu erleichtern , zeichne einfach, was natürlich kommt. Sie können es später jederzeit aufräumen, wenn ' in die formale Dokumentation aufgenommen wird.

Antwort

Ich denke, was Sie hier suchen, ist ein Sequenzdiagramm . Mit diesen können Sie die Reihenfolge visualisieren, in der verschiedene Module aufrufen einander mithilfe von Pfeilen.

Das Erstellen eines Pfeils ist einfach:

  1. Zeichnen Sie Ihre Startklasse mit einer gepunkteten Linie darunter.
  2. Zeichnen Sie die nächste Klasse / Methode in der Anrufverfolgung mit einer gepunkteten Linie darunter
  3. Verbinden Sie die Linien mit einem Pfeil, der vertikal unter dem zuletzt gezeichneten Pfeil positioniert ist
  4. Wiederholen Sie die Schritte 2-3 für alle Anrufe in Ihrer Ablaufverfolgung

Beispiel

Nehmen wir an, wir haben den folgenden Code, für den wir ein Sequenzdiagramm erstellen möchten:

def long_division(quotient, divisor): solution = "" remainder = quotient working = "" while len(remainder) > 0: working += remainder[0] remainder = remainder[1:] multiplier = find_largest_fit(working, divisor) solution += multiplier working = calculate_remainder(working, multiplier, divisor) print solution def calculate_remainder(working, multiplier, divisor): cur_len = len(working) int_rem = int(working) - (int(multiplier) * int (divisor)) return "%*d" % (cur_len, int_rem) def find_largest_fit(quotient, divisor): if int(divisor) == 0: return "0" i = 0 while i <= 10: if (int(divisor) * i) > int(quotient): return str(i - 1) else: i += 1 if __name__ == "__main__": long_division("645", "5") 

Als erstes zeichnen wir den Einstiegspunkt (main), der mit der Methode long_division verbunden ist Beachten Sie, dass dadurch ein Feld in long_ erstellt wird Division, die den Umfang des Methodenaufrufs angibt. In diesem einfachen Beispiel entspricht das Feld der gesamten Höhe unseres Sequenzdiagramms, da dies das einzige ausgeführte Element ist.

Geben Sie hier die Bildbeschreibung ein.

Jetzt rufen wir find_largest_fit auf, um das größte Vielfache zu finden, das in unsere Arbeitsnummer passt und gibt es uns zurück. Wir ziehen eine Linie von long_division zu find_largest_fit mit einem anderen Feld, um den Bereich für den Funktionsaufruf anzugeben. Beachten Sie, wie das Feld endet, wenn der Multiplikator zurückgegeben wird. Dies ist das Ende dieses Funktionsumfangs!

Geben Sie hier die Bildbeschreibung ein

Wiederholen Sie dies einige Male für eine größere Zahl, und Ihr Diagramm sollte ungefähr so aussehen:

Geben Sie ein Bildbeschreibung hier

Hinweise

Sie können wählen, ob Sie die Aufrufe mit den übergebenen Variablennamen oder deren Werten kennzeichnen möchten, wenn Sie dies nur möchten einen bestimmten Fall dokumentieren. Sie können die Rekursion auch mit einer Funktion anzeigen, die sich selbst aufruft.

Außerdem können Sie hier Benutzer anzeigen und sie dazu auffordern und ihre Eingaben in das System einfach genug anzeigen. Es ist ein ziemlich flexibles System, von dem ich denke, dass Sie es ziemlich nützlich finden werden!

Kommentare

  • Danke, ich kenne das Sequenzdiagramm, aber es fühlt sich für mich eher für oop geeignet an. In meinem Fall sind die Dinge etwas chaotischer, was bedeutet, dass ich zum Beispiel ungefähr 20 Funktionen / Helfer habe, die auf mehrere Module verteilt sind. Wie würde ich das Modul angeben, zu dem die Funktion gehört? In Anbetracht dessen, dass einige Funktionen auch während des Imports umbenannt werden.
  • Ich würde sagen, dass es keine Rolle spielt, wie viele Module Sie haben – das obige Beispiel ist auch überhaupt nicht in Ordnung. Benennen Sie sie einfach, damit Sie sie später finden können: ModulA / Funktion1, ModulB / Funktion2 usw. Für 20 Funktionen wird es größer, aber definitiv nicht unmöglich zu verstehen. Sie können auch die Zeile für eine Funktion nach ihrer letzten Verwendung beenden und eine weitere Funktionszeile darunter einfügen, um horizontalen Platz in Ihrem Diagramm zu sparen.

Antwort

Ich denke, ein Anrufdiagramm wäre die am besten geeignete Visualisierung.Wenn Sie sich entscheiden, dies nicht von Hand zu tun, gibt es „ein nettes kleines Tool namens pyan, das eine statische Analyse einer Python-Datei durchführt und mithilfe eines graphviz-Punkts ein visualisiertes Aufrufdiagramm erstellen kann Datei (die in ein Bild gerendert werden kann). Es gab einige Gabeln, aber die am besten ausgestattete scheint https://github.com/davidfraser/pyan .

Sie müssen nur alle Dateien angeben, die verarbeitet werden sollen, wenn Sie den Befehl ausführen:

python ~/bin/pyan.py --dot a.py b.py c.py -n > pyan.dot; dot -Tpng -opyan.png pyan.dot

oder

python ~/bin/pyan.py --dot $(find . -name "*.py") -n > pyan.dot; dot -Tpng -opyan.png pyan.dot

Sie können das Diagramm mit dem „-n“ sauberer machen, wodurch das entfernt wird Linien, die zeigen, wo eine Funktion definiert wurde.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.