2012-12-20 1 views
31

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 que c'est très déroutant. Je ne suis pas en mesure d'exécuter le code car il a besoin de HW et SW supplémentaires pour le faire. Cependant, j'ai besoin de comprendre la logique derrière cela. Donc, j'ai besoin de savoir s'il existe un outil (qui ne nécessite aucune exécution de fichier python) qui peut construire un graphe d'appel en utilisant les modules au lieu de l'analyseur de trace ou de python. J'ai de tels outils pour C mais pas pour python.
Merci.Construire un graphe d'appel en python incluant les modules et les fonctions?

Répondre

4

En résumé, aucun outil de ce type n'existe. Python est beaucoup trop dynamique d'un langage pour pouvoir générer un graphe d'appel sans exécuter le code.

est ici un code qui démontre clairement quelques-unes des caractéristiques 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 aussi en utilisant getattr d'appeler l'un de ses méthodes. Ce sont les deux méthodes qui rendraient extrêmement difficile la création d'un graphe d'appel statique pour python. De plus, il existe toutes sortes de méthodes d'importation de modules difficiles à analyser.

Je pense que votre meilleur pari va être de s'asseoir avec la base de code et un bloc de papier, et 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.

+0

Je sais. Tout au plus, on pourrait rechercher les instructions _import_, _def_ et _func() _ dans les modules. Je pense que je vais écrire un programme pour faire exactement cela. Bien sûr, cela ne fonctionnera que sur les simples codes source _simple_. – JohnnyDH

+0

Seulement * extrêmement * simples. Vous aurez également besoin d'analyser les commentaires, les chaînes et les docstrings, de peur que vous ne soyez trompés par ceux-ci. J'ai édité ma réponse pour inclure ce que je pense que vous devriez réellement faire. – Wilduck

+2

Oui, je le fais manuellement ... Il y a 14 scripts référencés ... Souhaitez-moi bonne chance :) – JohnnyDH

20

Vous pouvez consulter pycallgraph:

pycallgraph

également dans ce lien une approche plus manuelle est décrite:

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

+2

Oui, j'ai vu cette page au cours de mes recherches mais je suis à la recherche d'une solution "professionnelle". J'ai peur qu'une telle chose n'existe pas ... Nouvelle idée de start-up? Hehe – JohnnyDH

+0

Pycallgraph ne digère pas bien les paquets malheureusement – chiffa

+3

pycallgraph exécute le code, ce qui est ce qu'il a demandé de ne pas faire. pyan fait l'analyse statique (voir ma réponse ci-dessous) –

16

Le meilleur outil que j'ai trouvé est appelé pyan, et était originally written par Edmund Horner, improved by him, puis given colorization et d'autres par Juha Jeronen. Cette version dispose d'options en 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] 

est ici le résultat de l'exécution pyan.py --dot -c -e pyan.py | fdp -Tpng:

pyan's output on itself

code original de Edmund Horner est maintenant mieux trouvé in his github repository, et quelqu'un a également fait une repository with both versions, d'où vous pouvez download Juha Jeronen's version. J'ai fait une version propre combinant leurs contributions en my own repository just for pyan, puisque les deux dépôts ont beaucoup d'autres logiciels.

+0

J'ai pris à regarder votre propre référentiel. Le code ne vient pas avec une licence de copyright, donc il n'y a pas de relâchement vérifiable des droits réservés - cela signifie qu'il est interdit aux gens de l'utiliser tel quel ... Êtes-vous en mesure d'ajouter une licence comme la licence MIT? propager et définir une référence pour les rapports de code Python? – codeshot

+0

Bon point. Ils ont été publiés à l'origine sous la licence GPL v2, j'ai donc mis à jour le code pour le montrer, et j'ai laissé un [commentaire de blog] (https://ejrh.wordpress.com/2012/08/18/coloured-call-graphs/ # comment-1365) pour le vérifier –

+0

@DavidFraser est-il compatible avec Python 3.x? –

-3

Aucun outil de ce type n'existe pour aucun programme dans aucune langue. Créer un tel outil équivaudrait à résoudre le problème de l'arrêt, qui est indécidable. Autrement dit, étant donné un programme arbitraire et sa saisie, il n'y a pas d'algorithme pour déterminer si le programme s'arrêtera ou tournera indéfiniment. De même, aucun algorithme ne peut déterminer si la fonction x appellera la fonction y, ou si une certaine ligne de code sera exécutée, etc. Il est clair que pour certains programmes, il est possible de déterminer ces comportements. Par exemple, un programme de 1 ligne avec une instruction d'impression exécutera trivialement une ligne et quittera. Mais les programmes arbitraires peuvent être arbitrairement complexes, de sorte qu'il peut être prouvé qu'aucun algorithme n'existe pour déterminer ces comportements pour un programme arbitraire. Malheureusement, vous devez être en mesure d'exécuter le programme pour résoudre ce problème.

+1

Mais vous pouvez effectuer une première recherche de l'espace de tous les appels possibles.Un utilisateur peut arrêter la création du graphique à certains point, et appelez le programme "trop ​​dur". – codeshot

Questions connexes