Construire un graphique D'appel en python incluant des modules et des fonctions?
j'ai un tas de scripts pour effectuer une tâche. Et j'ai vraiment besoin de connaître le graphique d'appel du projet parce qu'il est très confus. Je ne suis pas capable d'exécuter le code parce qu'il a besoin de HW et SW supplémentaires pour le faire. Cependant, j'ai besoin de comprendre la logique derrière elle. Donc, j'ai besoin de savoir s'il existe un outil (qui ne nécessite pas d'exécution de fichier python) qui peut construire un graphique d'appel en utilisant les modules au lieu de l'analyseur trace ou python. J'ai de tels outils pour C mais pas pour Python.
Remercier.
4 réponses
Vous pourriez vouloir vérifier pycallgraph:
également dans ce lien une approche plus manuelle est décrite:
génération d'appel-graphiques-pour-comprendre-et-refactoring-python-code
le meilleur outil que j'ai trouvé s'appelle pyan
et initialement écrit par Edmund Horner,amélioration par lui et compte tenu de la colorisation et d'autres fonctionnalités par Juha Jeronen. Cette version a des options de ligne de commande utiles:
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]
Voici le résultat de l'exécution pyan.py --dot -c -e pyan.py | fdp -Tpng
:
le code original D'Edmund Horner est maintenant le mieux trouvé dans son dépôt github, et quelqu'un l'a également fait un dépôt avec les deux versions, d'où vous pouvez téléchargez la version de Juha Jeronen. J'ai fait une version propre combinant leurs contributions en mon propre dépôt juste pour pyan, puisque les deux dépôts ont beaucoup d'autres logiciels.
en bref, il n'existe pas d'outil de ce type. Python est beaucoup trop dynamique d'un langage pour pouvoir générer un graphique d'appel sans exécuter le code.
voici du code qui démontre clairement certaines des fonctionnalités très dynamiques de python:
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)
notez que nous utilisons eval
pour créer une instance de my_obj
et getattr
pour appeler une de ses méthodes. Ce sont deux méthodes qui rendraient extrêmement difficile la création d'un graphe d'appel statique pour python. En outre, il ya toutes sortes de difficiles à analyser les façons d'importer des modules.
je pense que votre meilleur pari sera de s'asseoir avec le code de base et un bloc de papier, et de commencer à prendre des notes à la main. Cela aura le double avantage de vous familiariser avec la base de code, et ne sera pas facilement trompé par des scénarios difficiles à analyser.
aucun outil de ce type n'existe pour un programme dans une langue quelconque. La création d'un tel outil serait équivalent à résoudre le problème de l'arrêt, qui est indécidable. En termes simples, étant donné un programme arbitraire et son entrée, il n'y a pas d'algorithme pour déterminer si le programme va s'arrêter ou courir pour toujours. De même, aucun algorithme ne peut déterminer si la fonction x appellera la fonction y, ou si une certaine ligne de code s'exécutera, etc. Clairement, pour certains programmes, on peut déterminer ces comportement. Par exemple, un programme de 1 ligne avec une instruction d'impression exécutera trivialement la ligne une et la sortie. Mais arbitraires, les programmes peuvent être arbitrairement complexe, de sorte qu'il peut être prouvé qu'aucun algorithme n'existe pour déterminer ces comportements pour un programme quelconque. Malheureusement, vous devez être en mesure d'exécuter le programme pour résoudre ce problème.