2012-12-20 10 views
31

Ich habe eine Reihe von Skripten, um eine Aufgabe auszuführen. Und ich muss wirklich das Aufrufdiagramm des Projekts kennen, weil es sehr verwirrend ist. Ich kann den Code nicht ausführen, weil dafür zusätzliche Hardware und Software benötigt wird. Ich muss jedoch die Logik dahinter verstehen. Ich muss also wissen, ob es ein Tool gibt (das keine Python-Dateiausführung erfordert), das ein Aufrufdiagramm mit den Modulen anstelle des Trace- oder Python-Parsers erstellen kann. Ich habe solche Werkzeuge für C, aber nicht für Python.
Danke.Erstellen Sie ein Call-Graph in Python mit Modulen und Funktionen?

Antwort

4

Kurz gesagt, ein solches Werkzeug existiert nicht. Python ist viel zu dynamisch in einer Sprache, um einen Aufrufgraphen generieren zu können, ohne den Code auszuführen.

Hier einige Code, der eindeutig einige der sehr dynamischen Eigenschaften von Python zeigt:

class my_obj(object): 
    def __init__(self, item): 
     self.item = item 
    def item_to_power(self, power): 
     return self.item ** power 

def strange_power_call(obj): 
    to_call = "item_to_power" 
    return getattr(obj, to_call)(4) 

a = eval("my" + "_obj" + "(12)") 
b = strange_power_call(a) 

Bitte beachte, dass wir eval verwenden eine Instanz von my_obj zu erstellen und auch getattr mit einem seiner Methoden aufrufen. Dies sind beide Methoden, die es extrem schwierig machen würden, ein statisches Aufrufdiagramm für Python zu erstellen. Darüber hinaus gibt es alle Arten von schwer zu analysierenden Möglichkeiten, Module zu importieren.

Ich denke, Ihre beste Wette wird sein, sich mit der Codebasis und einem Blatt Papier hinzusetzen und Notizen von Hand zu machen. Dies hat den doppelten Vorteil, dass Sie mit der Codebasis vertrauter werden und nicht leicht von schwer zu parsenen Szenarien ausgetrickst werden können.

+0

Ich weiß. Man könnte höchstens nach _import_, _def_ und _func() _ Anweisungen innerhalb der Module suchen. Ich denke, ich werde ein Programm schreiben, um genau das zu tun. Natürlich wird es nur für _simple_ Quellcodes funktionieren. – JohnnyDH

+0

Nur * extrem * einfache. Sie müssen auch Kommentare, Strings und Docstrings parsen, damit Sie nicht dazu täuschen. Ich habe meine Antwort so bearbeitet, dass sie enthält, was ich eigentlich tun sollte. – Wilduck

+2

Ja, ich mache es manuell ... Es gibt 14 referenzierte Skripte ... Wünsch mir Glück :) – JohnnyDH

20

Vielleicht möchten check out pycallgraph:

pycallgraph

Auch in diesem Link eine manuelle Ansatz beschrieben:

generating-call-graphs-for-understanding-and-refactoring-python-code

+2

Ja, ich habe diese Seiten während meiner Recherche gesehen, aber ich bin auf der Suche nach einer "professionellen" Lösung. Ich fürchte, so etwas gibt es nicht ... Neue Start-up-Idee? Hehe – JohnnyDH

+0

Pycallgraph nicht gut Pakete gut verdauen – chiffa

+3

pycallgraph läuft den Code, der ist, was er nicht tun wollte. Pyan macht statische Analyse (siehe meine Antwort unten) –

16

Das beste Werkzeug, das ich gefunden habe aufgerufen pyan, und war originally written von Edmund Horner, improved by him, und dann given colorization und andere Funktionen von Juha Jeronen. Diese Version hat nützliche Optionen Kommandozeile:

Usage: pyan.py FILENAME... [--dot|--tgf] 

Analyse one or more Python source files and generate an approximate call graph 
of the modules, classes and functions within them. 

Options: 
    -h, --help   show this help message and exit 
    --dot    output in GraphViz dot format 
    --tgf    output in Trivial Graph Format 
    -v, --verbose  verbose output 
    -d, --defines  add edges for 'defines' relationships [default] 
    -n, --no-defines  do not add edges for 'defines' relationships 
    -u, --uses   add edges for 'uses' relationships [default] 
    -N, --no-uses  do not add edges for 'uses' relationships 
    -c, --colored  color nodes according to namespace [dot only] 
    -g, --grouped  group nodes (create subgraphs) according to namespace 
         [dot only] 
    -e, --nested-groups create nested groups (subgraphs) for nested namespaces 
         (implies -g) [dot only] 

Hier ist das Ergebnis pyan.py --dot -c -e pyan.py | fdp -Tpng des Laufens:

pyan's output on itself

Edmund Horner-Original-Code ist jetzt am besten in his github repository gefunden, und jemand hat auch eine repository with both versions, von wo aus Sie können download Juha Jeronen's version. Ich habe eine saubere Version gemacht, die ihre Beiträge in my own repository just for pyan kombiniert, da beide Repositories viele andere Software haben.

+0

Ich nahm bei Blick auf Ihr eigenes Repository. Der Code enthält keine Urheberrechtslizenz, daher gibt es keine nachweisbare Lockerung der reservierten Rechte - das heißt, es ist verboten, sie so zu benutzen, wie sie ist ... Können Sie eine Lizenz wie die MIT-Lizenz hinzufügen, so kann diese Technik verbreiten und eine Basis für Python-Code-Berichte setzen? – codeshot

+0

Guter Punkt. Sie wurden ursprünglich unter der GPL v2 veröffentlicht, also habe ich den Code aktualisiert, um dies zu zeigen, und einen [Blog-Kommentar] hinterlassen (https://ejrh.wordpress.com/2012/08/18/coloured-call-graphs/ # comment-1365) um dies zu überprüfen –

+0

@DavidFraser ist es kompatibel mit Python 3.x? –

-3

Kein solches Werkzeug existiert für irgendein Programm in irgendeiner Sprache. Die Erstellung eines solchen Werkzeugs wäre gleichbedeutend mit der Lösung des Halteproblems, das unentscheidbar ist. Einfach gesagt, gibt es bei einem beliebigen Programm und dessen Eingabe keinen Algorithmus, um zu bestimmen, ob das Programm für immer anhält oder läuft. Ebenso gibt es keinen Algorithmus, der bestimmen kann, ob die Funktion x die Funktion y aufruft oder ob eine bestimmte Codezeile ausgeführt wird usw. Für bestimmte Programme kann man diese Verhaltensweisen eindeutig bestimmen. ZB wird ein 1-zeiliges Programm mit einer print-Anweisung die eine Zeile trivial ausführen und beenden. Aber willkürliche Programme können beliebig komplex sein, so dass bewiesen werden kann, dass kein Algorithmus existiert, um diese Verhaltensweisen für ein beliebiges Programm zu bestimmen. Leider müssen Sie in der Lage sein, das Programm auszuführen, um dieses Problem zu lösen.

+1

Aber Sie können eine breite erste Suche nach dem Raum aller möglichen Anrufe durchführen. Ein Benutzer kann die Erstellung des Graphen bei einigen stoppen Zeigen Sie und nennen Sie das Programm "zu schwer". – codeshot